lubeda / EspHoMaTriXv2

A simple DIY status display with a 8x32 RGB LED matrix, implemented with esphome.io and Home Assistant.
MIT License
298 stars 29 forks source link

[FEATURE REQUEST] Add transparency to Icons #88

Closed andrewjswan closed 1 year ago

andrewjswan commented 1 year ago

Feature Request

Describe the solution / feature you'd like

Add transparency to Icons. At higher brightness, the black background in the icons starts to appear as a gray background (screenshot below). Is it possible to make the black background transparent (always black). Then the icons will look more harmoniously on the matrix at any brightness.

Judging by the documentation and source code ESPHome supports icons with transparency, even in the RGB565 icon type used. https://github.com/esphome/esphome/blob/dev/esphome/components/image/__init__.py#L321-L325

0x0020 as I understand it is RGB - [0,0,32], i.e. by enabling transparency we should get completely black color for all colors below [0,0,32].

Additional context

image

andrewjswan commented 1 year ago

Or maybe you can do like the good old days, add a transparency property to the icon, and use the top left pixel as the transparent color. Or black, transparent.

lubeda commented 1 year ago

I eee the problem but as you stated it's a "problem" of the ESPHOME components, a work around is editing the icons in gimp and change all transparent part to black.

trip5 commented 1 year ago

Actually, it may not be an ESPHome problem. ESPHome relies on Pillow to transform the images, doesn't it?

andrewjswan commented 1 year ago

it's a "problem" of the ESPHOME components

As far as I understood the source code, ESPHome when loading a picture, if the transparency property is specified, processes it and discards everything below a certain level, makes rgb = 0, and as a result it is black on the address LEDs, i.e. the diode is not lit. We load the picture as a stream using PIL and directly publish the picture to ESPHome and without specifying the property - has transparency.

trip5 commented 1 year ago

Yeah, I already tried messing with Pillow inside the ESPHome container and it made me super-grumpy.

How's this for a solution? Use ImageMagick to transform all transparencies to black...

https://imagemagick.org/script/download.php (BTW no need to install "convert")

Here's a windows CMD line that can iterate through all .gif files in a folder, just CD to the folder first.

for /r %i in (*.gif) do magick convert "%i" -alpha deactivate -black-threshold 0 -background black "%i"

Not sure about the -black-threshold option (0 to 255 all worked equally) but there shouldn't be any "almost black" pixels in the .gif anyways, right? And it didn't mess up any of my dark grey pixels.

Not the most ideal solution, but you shouldn't have to do it often.

This seems to preserve the alpha transparent channel but turns it all black and deactivates it... I recommend making a backup ZIP of all your GIF files, just in case. And it doesn't work perfectly still... the black pixels are still lit, just barely but a lot less than before.

Example Input: humidity

Example Output: humidity

You can reactivate the alpha channel (which is now black) with this:

for /r %i in (*.gif) do magick convert "%i" -alpha background "%i"

Reactivated Black Alpha: humidity

Yeah, they don't seem to appear very different here, but the result is very pleasing. I'm not entirely sure the pixels are turned off completely but they certainly appear to be black... and it had the added bonus of fixing my legacy Awtrix icons which had no transparency, only a black background.

Edits: Sorry if you viewed this while I was editing it. I wanted to get it right.

Sidenote: perhaps we need an icon repository much like Awtrix has? Would Github allow directly linking from yaml files?

trip5 commented 1 year ago

Oh and if you want that in a .cmd or .bat file, be sure to change all % to %% yeah?

andrewjswan commented 1 year ago

How's this for a solution? Use ImageMagick to transform all transparencies to black...

Does this solve the problem of the matrix displaying gray instead of black at maximum brightness?

trip5 commented 1 year ago

It's cloudy weather here... So I can't verify 100%. You know, the problem is most visible with real sunlight... But I used a flashlight to bring to maximum brightness and it seems like mostly fixed. The pixels appear to be on at a minimum so at least they're black and not Grey.

The problem is mostly because of the source file I think... I can't even remember which icon source I used. It for the original pixel clock and Awtrix also linked to it. Anyway they used gray pixels with an alpha channel...

andrewjswan commented 1 year ago

I use everywhere LaMetric icons from the site, it would not be bad if during the build they would be downloaded and cached in some directory (interesting idea in my opinion). :)

In principle it is not difficult to download them all and process them with ImageMagick, but it seems to me that this should be solved by ESPHome settings, especially since it supports transparency and we can always convert them before packing them into an ESPHome resource.

andrewjswan commented 1 year ago

Maybe this is where you should add code like ESPHome does? https://github.com/lubeda/EspHoMaTriXv2/blob/main/components/ehmtxv2/__init__.py#L364

rgb = (R << 11) | (G << 5) | B
if rgb == 0x0020:
  rgb = 0

Then the code of loading a picture, will take into account the transparency, as it is done in ESPHome, well, or to each icon to add a sign of transparency, and then change the code to such a code:

rgb = (R << 11) | (G << 5) | B
if transparent:
  if rgb == 0x0020:
    rgb = 0
andrewjswan commented 1 year ago

It is also possible to try to convert not to RGB but to RGBA and repeat the ESPHome code in EspHoMaTriXv2. https://github.com/lubeda/EspHoMaTriXv2/blob/main/components/ehmtxv2/__init__.py#L344 Change to:

frame = image.convert("RGBA")

and https://github.com/lubeda/EspHoMaTriXv2/blob/main/components/ehmtxv2/__init__.py#L364 To:

rgb = (R << 11) | (G << 5) | B
if rgb == 0x0020:
  rgb = 0
if a < 0x80:
  rgb = 0x0020

or to

rgb = (R << 11) | (G << 5) | B
if transparent:
  if rgb == 0x0020:
    rgb = 0
  if a < 0x80:
    rgb = 0x0020

ESPhome code: https://github.com/esphome/esphome/blob/dev/esphome/components/image/__init__.py#L310-L330

Or something like that.

lubeda commented 1 year ago

Please check the 2023.8.0 version

andrewjswan commented 1 year ago

That's great! I hope this solves this problem. I'll have to upgrade to 2023.8 and check it out. Thanks a lot!

PS: When can we expect the 2023.8 release? :)

trip5 commented 1 year ago

I was just digging into Pillow and found that RGBA is the key. Thanks, lubeda!

Sidenote that although we can still use LaMetric as a source, some of my research found that the style of conversion I show above (converting all transparent pixels to a uniform color) help compress the image since apparently some pictures may contain different color values for transparent pixels... Although this might not seem like much of a difference, it can add up - especially in compression - and this could help @andrewjswan in his quest for >100 icons.

I have 28 8x8 GIFs (all animated): Before ImageMagick: 10268 bytes After ImageMagick: 10222 bytes

I tested by putting them in a normal compression ZIP file (with WinRAR): Before ImageMagick: 9065 bytes After ImageMagick: 8749 bytes

So, maybe only a 3% savings overall, but still... something. I imagine that due to the way compression works, the more pictures you have, the more significant the savings.

andrewjswan commented 1 year ago

in his quest for >100 icons.

I'm still on an older version, so I have 90 of them, but I don't want to increase them much, for example duplicate weather icons, for weather forecast icons, so I want to use them on different screens. But I can't do that yet.

malinovsku commented 1 year ago

in version 2023.08, the highlighted transparent background on some icons has disappeared, it's super! But for example there is also a background on this icon https://pixelit .bastelbunker.de/images/543.gif is it possible to fix it in the same way? 543

https://github.com/lubeda/EspHoMaTriXv2/assets/34610364/d99a8a0b-43cb-4d5c-884f-22df39d01a53

lubeda commented 1 year ago

Changed the threshold, so this shows more black, but all scaled images may cause problems, e.g. inside the "D" there are some pixels not black but dark blue.