2017-08-09 245 views
0

我目前使用Python 2.7从一系列位图中提取像素信息,并将24位信息写入文件(使用任意扩展名“.bfs” ,以便于查找管道),位置x为8位,位置y为8位,颜色为16位。在Python中写入文件,使用Arduino从文件中读取

from PIL import Image 
import struct 

filename = raw_input('Please choose destination filename: ') 

file_in = [0]*27 
im = [0]*27 

for i in range(1,27): 
    file_in[i] = str(i)+".bmp" 
    im[i] = Image.open(file_in[i]) 

file_out = open(filename+".bfs", 'w') 
readable_out = open(filename+".txt", 'w') 

for q in range(1,27):  
    pix = im[q].load() 
    width, height = im[q].size 
    for y in range (height): 
     for x in range (width): 
      rgb = pix[x,y] 

      red = rgb[0] 
      green = rgb[1] 
      blue = rgb[2] 

      Uint16_val = (((31*(red+4))/255)<<11) | (((63*(green+2))/255)<<5) | ((31*(blue+4))/255) 
      hex_16 = int('%.4x'%Uint16_val, 16) 
      print(str(x)+", "+str(y)+", "+str(hex_16)+"\n") 

      readable_out.write(str(x)+", "+str(y)+", "+str(hex_16)+"\n") 

      file_out.write(struct.pack('<1B', x)) 
      file_out.write(struct.pack('<1B', y)) 
      file_out.write(struct.pack('<1H', hex_16)) 

在PC方面一切都出来干净我怎么想到(这是从一个.txt文件复制的I输出和格式,使之更易于阅读):

0, 0, 40208 
1, 0, 33544 
2, 0, 33544 
3, 0, 39952 
4, 0, 39944 
5, 0, 33544 
6, 0, 39688 
7, 0, 39952 
8, 0, 39944 
9, 0, 33544 
10, 0, 33800 
11, 0, 39952 
12, 0, 39952 
13, 0, 33544 
14, 0, 33800 
15, 0, 48400 

从这里我将.bfs文件加载到SD卡上,供Arduino Uno读取。 Arduino代码应该从SD卡读取,并将x,y和颜色值输出到TFT LCD。下面是Arduino的代码:

#include <Adafruit_GFX.h> // Core graphics library 
#include <Adafruit_ST7735.h> // Hardware-specific library 
#include <SPI.h> 
#include <SD.h> 

#define TFT_CS 10 // Chip select line for TFT display 
#define TFT_RST 9 // Reset line for TFT (or see below...) 
#define TFT_DC 8 // Data/command line for TFT 

#define SD_CS 4 // Chip select line for SD card 

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); 

void setup(void) { 
    Serial.begin(9600); 

    tft.initR(INITR_144GREENTAB); 


    Serial.print("Initializing SD card..."); 
    if (!SD.begin(SD_CS)) { 
    Serial.println("failed!"); 
    return; 
    } 
    Serial.println("OK!"); 

tft.fillScreen(0x0000); 
} 

uint32_t pos = 0; 
uint8_t x,y; 
uint8_t buffpix[3]; 
uint16_t c; 

void loop() { 
bfsDraw("image.bfs"); 
} 

#define BUFFPIXEL 20 

void bfsDraw(char *filename) { 

    File  bfsFile; 
    int  w, h, row, col; 
    uint8_t x,y; 
    uint16_t c; 
    uint32_t pos = 0, startTime = millis(); 

    if((0 >= tft.width()) || (0 >= tft.height())) return; 

    if ((bfsFile = SD.open(filename)) == NULL) { 
    Serial.print("File not found"); 
    return; 
    } 
     w = 128; 
     h = 128; 
     tft.setAddrWindow(0, 0, 0+w-1, 0+h-1); 

     for (row=0; row<h; row++) { 
      for (col=0; col<w; col++) { 
      x = bfsFile.read(); 
      Serial.print(x); 
      Serial.print(", "); 
      y = bfsFile.read(); 
      Serial.print(y); 
      Serial.print(", "); 
      c = read16(bfsFile); 
      Serial.print(c); 
      Serial.print(" "); 
      Serial.println(" "); 
      tft.drawPixel(x,y,c); 
      } 
     } 
    } 

uint8_t read8(File f) { 
    uint16_t result; 
    ((uint8_t *)&result)[0] = f.read(); 
    return result; 
} 

uint16_t read16(File f) { 
    uint16_t result; 
    ((uint8_t *)&result)[0] = f.read(); 
    ((uint8_t *)&result)[1] = f.read(); 
    return result; 
} 

我周围发出的TFT之前从卡中读取代码中的一些打印语句,而不是文件匹配(我认为)我写它输出这样:

0, 0, 40208 
1, 0, 33544 
2, 0, 33544 
3, 0, 39952 
4, 0, 39944 
5, 0, 33544 
6, 0, 39688 
7, 0, 39952 
8, 0, 39944 
9, 0, 33544 
13, 10, 2048 
132, 11, 4096 
156, 12, 4096 

正如你可以看到从Arduino的阅读开始了Python脚本的写作匹配,但9后的“X”字节已经转移到中间,而不是领先地位。我的问题是什么导致这种转变,在x = 9后?这是一个小endian与大endian问题?

感谢您的帮助!

回答

0

您以文本模式打开文件,而不是二进制模式。在Windows上,这意味着您编写的每个换行符(字节值10)都被转换为回车+换行符(字节值13,10)。打开.bfs文件时使用'wb'作为模式。

请注意,将每个像素的坐标写入文件是疯狂的 - 您将文件的大小加倍,绝对没有好处。在阅读文件时,您可以轻松地重新创建坐标 - 事实上,您已经以rowcol变量的形式实现!

+0

这样做了!我也欣赏关于文件优化的建议。我实际上计划在上游实施一些压缩技术,例如去除在帧之间重复的任何颜色/坐标序列。这应该有助于显着的文件大小(取决于复杂性)。如果我说我知道自己在做什么,我会撒谎,但我希望能获得有关此事的视频。我能够用RPi做到这一点(方式更快),大多数人都说这是不可能的,但这个人似乎不同意: http://blog.vinu.co.in/2012/06/avr-video-player -on-nokia-color-lcd.html 再次感谢! – user3596565