RGB565 support

Hi,

I’m using a LILYGO® TTGO T-Display ESP32 (http://www.lilygo.cn/prod_view.aspx?Id=1126) with 16MB flash size, and I need to display an animated GIF.
After modifying the partiton table to make full use of the 16MB (see https://community.home-assistant.io/t/how-to-increase-partition-size-to-use-16mb-of-flash-instead-of-4mb/364299/3)I loaded the gif using RGB24 type, but the colors where completely messed up.
According to the docs (https://esphome.io/components/display/st7789v.html), the ST7789V needs an RGB565 type, but it seems not supported and throws an error:

Failed config

image: [source /config/esphome/esphome-test.yaml:30]
  - [source /config/esphome/esphome-test.yaml:30]
    file: gifs/beer.jpg
    id: beer
    
    Unknown value 'RGB565', valid options are 'BINARY', 'GRAYSCALE', 'RGB24'.
    type: RGB565 [source /config/esphome/esphome-test.yaml:32]

Any hint?

/Marco

Your code?

This is a test YAML showing the problem. If I use RGB24 instead of RGB565, the code compiles without problems.

substitutions:
  devicename: prova
  upper_devicename: Prova
  deviceid: prova

esphome:
  name: esphome-${devicename}
  platform: ESP32
  board: featheresp32
  platformio_options:
    board_upload.flash_size: 16MB
    board_upload.maximum_ram_size: 327680
    board_upload.maximum_size: 16777216
    board_build.partitions: "../../../custom_partitions.csv"
  on_boot:
    then:
      - switch.turn_on: backlight
      - display.page.show: page_test
      - component.update: ttgo_display

animation:
  - file: "gifs/loop60x60.gif"
    id: spinloop
    type: GRAYSCALE
    # dither: FLOYDSTEINBERG
  - file: "gifs/beer-pour.gif"
    id: taploop
    type: RGB24
    # dither: FLOYDSTEINBERG

image:
  - file: "gifs/beer.jpg"
    id: beer
    type: RGB565

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_pass
  fast_connect: true

  ap:
    ssid: "esphome_${deviceid}"

captive_portal:

# Set up HTTP server
web_server:
  port: 80

## Set up HTTP client
http_request:
  useragent: esphome/device
  timeout: 5s

time:
  - platform: sntp
    id: esp_time

logger:
  level: DEBUG

switch:
  - platform: gpio
    pin: GPIO4
    name: ${upper_devicename} Backlight
    id: backlight

spi:
  clk_pin: GPIO18
  mosi_pin: GPIO19

display:
  - platform: st7789v
    backlight_pin: GPIO4
    cs_pin: GPIO5
    dc_pin: GPIO16
    reset_pin: GPIO23
    rotation: 90°
    brightness: 0.5
    update_interval: 0.2s
    id: ttgo_display
    pages:
      - id: page_test
        lambda: |-
          id(spinloop).next_frame();
          it.image(90, 60, id(spinloop));

Is the image rgb565 encoded?

Nope, it’s just a common image, but taking a look at the esphome code on github seems like it is an error in the documentation (there’s no “RGB565” string to be found anywhere in the source…).
Moreover I think that the image type is only related to how the image is embedded in the generated firmware, DisplayBuffer::image() uses it to loop throgh all the pixel and draw them with draw_pixel_at():

void DisplayBuffer::image(int x, int y, Image *image, Color color_on, Color color_off) {
  switch (image->get_type()) {
    case IMAGE_TYPE_BINARY:
      for (int img_x = 0; img_x < image->get_width(); img_x++) {
        for (int img_y = 0; img_y < image->get_height(); img_y++) {
          this->draw_pixel_at(x + img_x, y + img_y, image->get_pixel(img_x, img_y) ? color_on : color_off);
        }
      }
      break;
    case IMAGE_TYPE_GRAYSCALE:
      for (int img_x = 0; img_x < image->get_width(); img_x++) {
        for (int img_y = 0; img_y < image->get_height(); img_y++) {
          this->draw_pixel_at(x + img_x, y + img_y, image->get_grayscale_pixel(img_x, img_y));
        }
      }
      break;
    case IMAGE_TYPE_RGB24:
      for (int img_x = 0; img_x < image->get_width(); img_x++) {
        for (int img_y = 0; img_y < image->get_height(); img_y++) {
          this->draw_pixel_at(x + img_x, y + img_y, image->get_color_pixel(img_x, img_y));
        }
      }
      break;
  }
}

I don’t fully understand all the code, but RGB565 seems to have been changed to RGB here

And to RGB24 here

My conclusion is to change to

type: RGB24

Actually I don’t know what’s wrong with my project (spoiler: RGB24 doesn’t work, gives a smeared, B&W animation, that’s why I tried with RGB565), problem is RGB565 is used in some sample code in ST7789V docs (https://esphome.io/components/display/st7789v.html).

After your findings this definitely looks like a leftover from those PRs…

/M

Time for a github issue?

1 Like

I tried a PR, but don’t know if I made it right…
In the mean time I found the culprit of my messy animation: the animated GIF.
After splitting in single frames and then putting them back together, it finally works :smiley:

/M

Why is your gif named .jpg?

If you read the OP, I was trying to display an animated GIF (in my code, that would be beer-pour.gif).

Since it was not showing right, I made several tests to pin down the problem, which led me to try a simple image with type: RGB565, which in turn led to this thread and finding that RGB565 is not supported anymore.

After that, I found the problem in the original GIF not beeing rendered right…

1 Like

Hi, i made a pull request to esphome to strore images and animations in rgb565 format. Hopefully it will be merged in the next release.

Hope this helps.