Manual
do
Maker
.
com
Me perguntaram no canal youtube.com/@dobitaobyte como exibir gif animado no T-Display S3. Bem, vamos entender primeiramente o que é um gif animado.
Um git animado é uma sequência de imagens compostas que geram o efeito de animação. É bem parecido com um vídeo, mas o gif é composto por poucas imagens, enquanto um vídeo é "tolerável" a partir de 24 imagens por segundo.
Sendo um gif animado uma sequência de imagens e sabendo que para exibir uma imagem em display precisamos convertê-la em um array de bytes, o que precisamos fazer para exibir uma animação no display é extrair do gif animado as imagens, então convertê-las uma a uma. Daí devemos fazer sua exibição no display, com delay o suficiente para que não seja feita a troca rápida demais nem lenta demais. Esse trabalho é extremamente simples, mas deve ser feito por etapas. Bora começar?
A primeira etapa, obviamente, é ter o gif ou um webp animado.
Baixe o gif animado que deseja exibir no display, fazendo uma pesquisa no google, ou daqui, ou prepare uma sequência de imagens que você tenha aí.
A primeira forma que me vem à cabeça para extrair as imagens de um gif animado é com o programa ffmpeg. Ele possui versões para múltiplos sistemas operacionais. O comando será o mesmo para Linux, Windows ou Mac. Se optar por ele, deverá instalá-lo e usar linha de comando:
ffmpeg -i arquivo.gif -vsync 0 temp%d.png
No caso, passamos nosso arquivo (aqui nomeado como arquivo.gif) e a saída será imagens numeradas prefixadas com a palavra temp.
Se preferir, pode fazer em algum conversor online (como esse).
Agora entra em ação o EasyMaker. Esse programa é gratuito e no momento desse artigo (verifique a data de publicação), só compilei versão para WIndows. Se ainda não viu como é simples utilizá-lo, confira nesse vídeo ou nesse outro.
Crie um arquivo para cada frame, se preferir manter uma certa organização. Por exemplo, se for criar uma animação de 4 quadros, crie os arquivos img01.h, img02.h, img03.h, img04.h. Coloque o conteúdo de cada imagem em seu respectivo arquivo e não se esqueça de trocar os nomes das variáveis. O padrão da conversão com Easymaker é esse:
int img2display_width=80
int img2display_height=100
const unsigned short img2display[8000] ={
Troque pelo nome do respectivo arquivo:
int img01_width=80
int img01_height=100
const unsigned short img01[8000] ={
Esses arquivos supracitados devem fazer parte do seu projeto, obviamente. Os arquivos sugeridos devem ser criados a partir da própria IDE de desenvolvimento do Arduino, de modo a já estarem no local correto e disponíveis imediatamente junto ao sketch. Depois de ter criado os arquivos, seu sketch deverá conter as inclusões desses cabeçalhos contendo as imagens, no começo do sketch:
#include "img01.h"
#include "img02.h"
#include "img03.h"
#include "img04.h"
Para trocar as imagens, utilizamos um único sprite que comportará as trocas. Também precisamos de um temporizador para definir o intervalo de cada imagem.
Sobre sprites, se não leu os artigos relacionados a esse display, sugiro que leia para saber de que se trata.
O sketch que anima o gif da imagem de destaque é esse:
#include "Arduino.h"
#include "TFT_eSPI.h" /* Please use the TFT library provided in the library. */
#include "Wire.h"
#include "pin_config.h"
#include "img2dsp.h"
#include "img01.h"
#include "img02.h"
#include "img03.h"
#include "img04.h"
unsigned int timer = millis();
unsigned int next_frame = 0;
const unsigned short *gif[4] = {img01, img02, img03, img04};
#define RIGHT 0
#define LEFT 1
#define TOP 2
#define BOTTON 3
//Instância do TFT
TFT_eSPI tft = TFT_eSPI();
//Criando sprites, que serão aplicados na instância do TFT
TFT_eSprite sprite_gif = TFT_eSprite(&tft); //Aqui passamos o endereço (&) da instância
TFT_eSprite bg_sprite = TFT_eSprite(&tft); //Aqui passamos o endereço (&) da instância
uint8_t show_frame = 0;
void setup() {
Serial.begin(115200);
//inicia o objeto
tft.init();
//RGB para GBR, que é o formato utilizado
tft.setSwapBytes(true);
tft.setRotation(0); //Usando EasyMaker, 0. Senão, 3
//Criando uma área de sprite para o gif
sprite_gif.createSprite(64,64);
//Agora criamos o sprite do background
bg_sprite.createSprite(170,320);
////RGB para GBR, que é o formato utilizado
bg_sprite.setSwapBytes(true);
//Exibe a imagem da maneira tradicional. Ok, quando não tiver animação
tft.pushImage(0,0,170,320,img2display);
//Coloca a imagem no sprite
sprite_gif.pushImage(0,0,64,64,gif[0]);
//Exibe a imagem, removendo a cor preta, dando transparência
sprite_gif.pushSprite(40,40,TFT_BLACK);
}
void showEmoji(){
next_frame = millis()-timer;
if (next_frame > 300){
show_frame = show_frame > 2 ? 0 : show_frame+1;
timer = millis();
}
bg_sprite.pushImage(0,0,170,320,img2display);
sprite_gif.pushImage(0,0,64,64,gif[show_frame]);
sprite_gif.pushToSprite(&bg_sprite, 60, 120, TFT_BLACK);
bg_sprite.pushSprite(0,0);
}
void loop(){
showEmoji();
}
O vídeo estará disponível em nosso canal @dobitaobyte no Youtube. Se não é inscrito, dê esse apoio moral para motivar mais conteúdos!
Inscreva-se no nosso canal Manual do Maker no YouTube.
Também estamos no Instagram.
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.