2017-08-09 293 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