esphome / issues

Issue Tracker for ESPHome
https://esphome.io/
290 stars 34 forks source link

use_transparency: command removes the anti-aliasing from an image #6047

Open agillis opened 1 month ago

agillis commented 1 month ago

The problem

There seems to be an issue with the use_transparency: command. This seems to remove the anti-aliasing from the image.

This is my code

  - file: https://esphome.io/_static/logo-text-on-light.svg
    id: boot_logo
    type: RGB565
    resize: 470x95
```    use_transparency: true

If I use this

```image:
  - file: logo-text-on-light.png
    id: boot_logo
    type: RGB565
```    resize: 470x95

Where logo-text-on-light.png is https://esphome.io/_static/logo-text-on-light.svg converted to a PNG with a white background it works fine. So it seems that all fine detail on the edge of the letters is being remove when the image file is loaded and put on top of a white background by ESPhome.

### Which version of ESPHome has the issue?

2024.6.6

### What type of installation are you using?

pip

### Which version of Home Assistant has the issue?

latest

### What platform are you using?

ESP32

### Board

guition-esp32-s3-4848s040

### Component causing the issue

image:

### Example YAML snippet

```yaml
This is the code that displays the image on the screen

lvgl:
  displays:
    - display_id: my_display
  touchscreens:
    - touchscreen_id: my_touchscreen
  on_idle:
    - timeout: 10s
      then:
        - logger.log: idle timeout
        - if:
            condition:
              lvgl.is_idle:
                timeout: 5s
            then:
              - logger.log: LVGL is idle
    - timeout: 15s
      then:
        - logger.log: idle 15s timeout

      #- lvgl.pause:
      #- light.turn_off:
      #    id: display_backlight
      #    transition_length: 5s    

  style_definitions:
    - id: no_checked_color
      bg_color: 0xCC5E14
      text_color: 0xB6B6B6

  theme:
    btn:
      text_font: roboto24
      scroll_on_focus: true
      group: general
      radius: 25px
      width: 150px
      height: 109px
      pad_all: 10px
      shadow_width: 0 # This is required even though the default is suposed to be 0
      bg_color: 0x313131
      text_color: 0xB6B6B6
      checked:
        bg_color: 0xCC5E14
        text_color: 0xB6B6B6

  page_wrap: true

  top_layer:
    widgets:
      - obj:
          id: boot_screen
          layout: 
            type: flex
            flex_flow: COLUMN_WRAP 
          width: 480px
          height: 480px
          text_font: roboto24
          scrollbar_mode: 'off'
          bg_color: 0xffffff
          bg_opa: COVER
          radius: 0
          pad_all: 5
          widgets:
            - img:
                src: boot_logo
                pad_bottom: 10


### Anything in the logs that might be useful for us?

_No response_

### Additional information

I can include some pictures of the resulting image on the screen if that helps.
nagyrobi commented 1 month ago

Please do so.

agillis commented 1 month ago

This a PNG with a transparent background using the use_transparency: true test - use_transparency true

This is the same image with a white background and use_transparency: omitted

test - use_transparency false

As you can see the text fields are fine in both images but the text from the ESPhome logo has no anti-aliasing when use_transparency: true is uesd

agillis commented 1 month ago

Is there a reason I need to use RGB565 as the image type when I load an SVG? I tried RGB24 and RGBA but I get "no data" When I load my image. This may be part of the issue.

nagyrobi commented 1 month ago

In lvgl, that's the only format currently supported. As a workaround, you should simply convert the file manually on your PC and use it as PNG.

agillis commented 1 month ago

I tried that and it still has the same problem. The only way I can get it to work it no set the background of the PNG to the same color as the object background. Any time I use a transparent PNG it seems to remove all the anti-aliasing pixels.

I have tried converting the images to different formats 8-bit 16-bit, etc. Maybe we can come up with a command for ImageMagick that will work?

agillis commented 1 month ago

At some point Clyde will fix the issue with the RGBA image type in the LVGL code. That will resolve this issue.

guillempages commented 4 weeks ago

Just my 2 cts as the original implementer of the "use_transparency" option: In ESPHome, transparency is handled as a binary flag for each pixel: either the pixel is transparent and thus won't be drawn, or it is not transparent, and will be normally drawn.

When compiling the image into the firmware, the python pillow image transformation functions is being used. That code tries to get the transparency information from the original image and IIRC uses a threshold (alpha value > 127) to decide whether to make the pixel transparent or not. My assumption is that the anti aliasing is making use of intermediate alpha values, and they get lost when using a hard threshold as is the case.

RGBA should work better, as you mentioned

agillis commented 2 weeks ago

RGBA is probably the final solution but at the moment converting True Type Fonts to images using pillow seems to work fine. I don't know enough about the ESPHome code to know how it converters fonts to images but if it could do the same with svg files this problem would be resolved.