Hello all!
Just to share a small piece of code I have done to display gif on a TFT display (IC controller - ILI9340). I share it but actually it would be very nice if you could give me some advice or possible improvements.
It is composed of 2 parts: the first one on processing to convert the gif file into a text file (store on the SD card) and the 2nd one on the arduino itself.
Processing:
PImage img;
PrintWriter output;
String imageName = "arduino.gif";
String saveDir = "./textFiles/";
void setup() {
img = loadImage(imageName);
size(img.width, img.height);
output = createWriter(saveDir + imageName.substring(0, (imageName.length()-4)) + ".txt");
background(255, 255, 0);
int[][] imgPixels = new int[img.width][img.height];
int[] findedColors = new int[1];
int[][] b_pix = new int[img.width][img.height];
output.print(img.width + ",");
output.println(img.height);
for (int i = 0; i < img.height; i++) { // création du tableau représentant l'image avec la valeur de la couleur codée en 16bit et = à -1 si transparant (int imgPixels[x][y])
for (int j = 0; j < img.width; j++) {
color tmp = img.get(j, i);
int red = tmp >> 16 & 0xFF;
int green = tmp >> 8 & 0xFF;
int blue = tmp & 0xFF;
float alpha = alpha(tmp);
if(alpha == 255) {
imgPixels[j][i] = Color565(red, green, blue);
} else {
imgPixels[j][i] = -1;
}
}
}
findedColors[0] = imgPixels[0][0];
for (int i = 0; i < img.height; i++) { // création du tableau contenant les couleurs présentes dans l'image (int findedColors[num_couleur])
for (int j = 0; j < img.width; j++) {
boolean flag = false;
for(int k = 0; k < findedColors.length; k++) {
if(findedColors[k] == imgPixels[j][i]) {
flag = true;
}
}
if(!flag) {
findedColors = append(findedColors, imgPixels[j][i]);
}
}
}
for(int i = 0; i < findedColors.length-1; i++) {
output.print(findedColors[i] + ",");
}
output.println(findedColors[findedColors.length-1]);
for(int k = 0; k < findedColors.length; k++) { // création du tableau d'entier représantant les coupeurs de pixels coresspondant (int b_pix[x][y])
for (int i = 0; i < img.height; i++) {
for (int j = 0; j < img.width; j++) {
if(findedColors[k] == imgPixels[j][i]) {
b_pix[j][i] = k;
}
}
}
}
for(int i = 0; i < img.height; i++) { // sauvegarde du tableau représentant l'image
for(int j = 0; j < img.width-1; j++) {
output.print(b_pix[j][i] + ",");
}
output.print(b_pix[img.width-1][i]);
if(i != img.height - 1)
output.print(',');
}
output.flush();
output.close();
}
void draw() {
image(img, 0, 0);
}
int Color565(int r, int g, int b) {
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}
the second on the uControler:
gif.h
class gif {
public:
File f_gif;
unsigned short n_width;
unsigned short n_height;
unsigned short n_colorN;
unsigned short n_color[];
unsigned long posColors;
unsigned long posPicture;
gif(File file);
unsigned short getColorsN();
void getColors();
void beginPicture();
unsigned short getPixelcolor();
int getVal();
unsigned short getWidth();
unsigned short getHeight();
void info();
};
gif.cpp
#include <SD.h>
#include "gif.h"
gif::gif(File file) {
this->f_gif = file;
this->n_width = getVal();
this->n_height = getVal();
this->posColors = this->f_gif.position();
this->n_colorN = getColorsN();
this->posPicture = this->f_gif.position();
getColors();
}
unsigned short gif::getColorsN(){
this->f_gif.seek(posColors);
unsigned short color = 0;
char tmp1 = this->f_gif.read();
while(this->f_gif.available() && tmp1 != '\r') {
if(tmp1 == ',') {
color++;
}
tmp1 = this->f_gif.read();
}
return color = color + 1;
}
void gif::getColors(){
this->f_gif.seek(this->posColors);
this->n_color[this->n_colorN];
for(int i = 0; i < this->n_colorN; i++) {
this->n_color[i] = getVal();
}
}
int gif::getVal() {
unsigned long initPos = this->f_gif.position();
unsigned short car = 0;
char tmp1 = this->f_gif.read();
while(tmp1 == '\n' || tmp1 == '\r') {
tmp1 = this->f_gif.read();
}
while(this->f_gif.available() && tmp1 != ',' && tmp1 != '\r') {
car++;
tmp1 = this->f_gif.read();
}
this->f_gif.seek(initPos);
char val[car+1];
int i = 0;
tmp1 = this->f_gif.read();
while(tmp1 == '\n' || tmp1 == '\r') {
tmp1 = this->f_gif.read();
}
while(i < car) {
val[i] = tmp1;
i++;
tmp1 = this->f_gif.read();
}
val[i] = NULL;
return atoi(val);
}
void gif::beginPicture() {
this->f_gif.seek(this->posPicture);
}
unsigned short gif::getPixelcolor() {
return this->n_color[getVal()];
}
unsigned short gif::getWidth() {
return this->n_width;
}
unsigned short gif::getHeight() {
return this->n_height;
}
void gif::info() {
Serial.print("n_width = ");
Serial.println(this->n_width);
Serial.print("n_height = ");
Serial.println(this->n_height);
Serial.print("n_colorN = ");
Serial.println(this->n_colorN);
Serial.print("posColors = ");
Serial.println(this->posColors);
Serial.print("posPicture = ");
Serial.println(posPicture);
for(int i = 0; i < this->n_colorN; i++) {
Serial.print("n_color[");
Serial.print(i);
Serial.print("] = ");
Serial.println(this->n_color[i]);
}
}
and the main
#include <Adafruit_GFX.h>
#include "Adafruit_ILI9340.h"
#include <SPI.h>
#include <SD.h>
#include "gif.h"
#define TFT_RST 9
#define TFT_DC 8
#define TFT_CS 10
#define SD_CS 4
Adafruit_ILI9340 tft = Adafruit_ILI9340(TFT_CS, TFT_DC, TFT_RST);
unsigned short num = 1;
unsigned short BGcolor;
void setup(void) {
Serial.begin(9600);
Serial.print("Initializing SD card... ");
if (!SD.begin(SD_CS)) {
Serial.println("failed!");
} else {
Serial.println("OK!");
}
tft.begin();
BGcolor = tft.Color565(1, 150, 156);
}
void loop() {
tft.fillScreen(BGcolor);
char fileName[] = "img/arduino.txt";
File imgFile = SD.open(fileName);
if (imgFile) {
gif logo = gif(imgFile);
logo.beginPicture();
int posX = 34;
int posY = 78;
//test.voir();
unsigned long debut = millis();
tft.setAddrWindow(posX, posY, posX+logo.getWidth()-1, posY+logo.getHeight()-1);
for(int i = 0; i < logo.getWidth()*logo.getHeight() - 1; i++) {
unsigned short pix = logo.getPixelcolor();
tft.pushColor(pix);
}
imgFile.close();
Serial.print(num);
Serial.print(" : The picture ");
Serial.print(fileName);
Serial.print(" was drawn in ");
Serial.print(millis()-debut);
Serial.println(" ms.");
num++;
} else {
Serial.print("error opening ");
Serial.println(fileName);
}
delay(10000);
tft.fillScreen(BGcolor);
char fileName1[] = "img/arduino1.txt";
File imgFile1 = SD.open(fileName1);
if (imgFile1) {
gif logo1 = gif(imgFile1);
logo1.beginPicture();
int posX = 34;
int posY = 78;
//test.voir();
unsigned long debut = millis();
tft.setAddrWindow(posX, posY, posX+logo1.getWidth()-1, posY+logo1.getHeight()-1);
for(int i = 0; i < logo1.getWidth()*logo1.getHeight() - 1; i++) {
unsigned short pix = logo1.getPixelcolor();
tft.pushColor(pix);
}
imgFile1.close();
Serial.print(num);
Serial.print(" : The picture ");
Serial.print(fileName1);
Serial.print(" was drawn in ");
Serial.print(millis()-debut);
Serial.println(" ms.");
num++;
} else {
Serial.print("error opening ");
Serial.println(fileName1);
}
delay(10000);
}
It takes 2.8 s to draw the arduino.txt file (172x85 pixels) and 4.1 s for arduino1.txt file (171x118 pixels).


arduino.txt (28.6 KB)
arduino1.txt (39.5 KB)