Imagens no TFT_eSPI: corrija cores RGB565 e a ordem de bytes

Se uma imagem tem a forma certa, mas as cores erradas no TFT_eSPI, teste duas coisas separadamente: a configuração RGB/BGR do display e a ordem de bytes dos dados da imagem. Mudar as duas ao mesmo tempo dificulta saber qual configuração resolveu o problema.
Um padrão pequeno é mais útil aqui do que uma fotografia. Vermelho, verde, azul, branco e preto dão valores que você reconhece sem adivinhar como a imagem original era.
Desenhe cores sólidas primeiro
Adicione esta função a um sketch que já inicializa o display corretamente. Chame ela depois de tft.init() e da sua configuração de rotação. Ela pressupõe que o objeto do display se chama tft e que a tela tem pelo menos 100 × 20 pixels.
void drawColorReference() {
const uint16_t colors[] = {
TFT_RED, TFT_GREEN, TFT_BLUE, TFT_WHITE, TFT_BLACK
};
for (int i = 0; i < 5; ++i) {
tft.fillRect(i * 20, 0, 20, 20, colors[i]);
}
}
Padrão de teste sintético, 100 × 20: cinco faixas iguais — vermelha, verde, azul, branca, preta. Não é uma fotografia de hardware. Baixe o PNG de referência e converta ele pelo seu conversor para comparar o caminho do recurso com a renderização de cores sólidas.
Se esses retângulos estão errados, trabalhe na configuração do display antes de converter outra imagem. O driver selecionado, as dimensões do painel e a ordem das cores pertencem à configuração do hardware. O User_Setup.h do TFT_eSPI documenta as opções relevantes, incluindo TFT_RGB_ORDER para os drivers compatíveis.
Se o vermelho aparece azul e o azul aparece vermelho, enquanto o verde continua verde, a ordem RGB/BGR é uma suspeita útil. Confira a configuração para o painel real, em vez de presumir que todo módulo vendido com o mesmo nome de controlador se comporta do mesmo jeito.
Depois teste o caminho da imagem
Quando os retângulos sólidos estiverem certos, envie um array RGB565 por pushImage(). Este segundo padrão é desenhado mais abaixo na tela, então reserve pelo menos 100 × 32 pixels no total:
void drawImageReference() {
static const uint16_t strip[] = {
0xF800, 0x07E0, 0x001F, 0xFFFF, 0x0000,
0xF800, 0x07E0, 0x001F, 0xFFFF, 0x0000
};
const bool previous = tft.getSwapBytes();
tft.setSwapBytes(false);
tft.pushImage(0, 24, 5, 2, strip);
tft.setSwapBytes(true);
tft.pushImage(0, 30, 5, 2, strip);
tft.setSwapBytes(previous);
}Isso produz dois padrões minúsculos de 5 × 2, um com cada configuração de troca. Inspecione qual corresponde às cores de referência. Use uma lupa se precisar; manter o array pequeno facilita auditar cada valor.
A biblioteca declara setSwapBytes() especificamente para a ordem de bytes dos pixels no seu cabeçalho da API. A configuração correta depende de como o recurso está armazenado e de qual caminho da API lê ele. Trate o resultado como uma verificação para aquela representação de recurso, e não como uma configuração universal para todo bitmap do projeto.
Trocar bytes não é trocar vermelho/azul
No RGB565, o vermelho é 0xF800. Os bytes dele são F8 e 00; inverter eles produz 0x00F8. Isso muda o valor numérico empacotado. Não troca simplesmente os canais vermelho e azul.
É por isso que dois sintomas precisam de verificações diferentes:
| O que você vê | O que conferir primeiro |
|---|---|
| Retângulos sólidos vermelhos e azuis trocados | Configuração RGB/BGR do painel |
| Retângulos sólidos certos, cores importadas erradas | Codificação do recurso e ordem de bytes |
| Linhas quebram ou formam faixas diagonais | Largura, altura e comprimento do array |
| Tudo em branco, incluindo os retângulos sólidos | Inicialização do display, fiação, backlight e driver |
Exporte o recurso para o TFT_eSPI
No Lopaka, selecione TFT_eSPI antes de importar a imagem e depois exporte os dados com a chamada de desenho gerada. Se você mudar a biblioteca de destino depois, gere o recurso de novo, em vez de levar o array de bytes antigo para o firmware novo.
Para o fluxo completo de layout, use o guia de UI para display TFT personalizado. O guia de integração do TFT_eSPI cobre a configuração do hardware e o código de desenho gerado.
Prepare primeiro o padrão de diagnóstico, depois o seu logotipo e depois a tela cheia. Se só a tela cheia falhar, você reduziu o problema àquele recurso ou ao caminho de memória que ele usa.
Perguntas frequentes
Devo sempre chamar setSwapBytes(true)?
Não. Combine a configuração com o array e o caminho de desenho. Restaure ela depois de um teste local, para a renderização posterior não herdar uma configuração que você esqueceu.
Um array RGB565 pode manter a transparência do PNG?
O RGB565 não tem componente alfa. Um PNG transparente precisa de um fundo escolhido ou de um método de desenho com suporte explícito à transparência. Uma borda escura ao redor de um logotipo pode vir de achatar ele contra o fundo errado.
Isso é diferente para ST7789 e ILI9341?
O teste funciona com qualquer um dos dois quando o TFT_eSPI já controla o painel. Os detalhes de configuração deles ainda são diferentes. Mantenha a configuração do painel que deixa as cores sólidas certas e depois diagnostique os recursos importados de forma independente.