CLImage icon indicating copy to clipboard operation
CLImage copied to clipboard

Image transparency with .png

Open kaclark opened this issue 2 years ago • 5 comments

Hello,

I have a .png file with transparent pixels and I would like to them to render as such due to an opacity setting on my tty that allows my desktop background image to be seen underneath. Is there any functionality for handling such pixels? If not, how could I start modifying this codebase to provide it?

This is the file that is giving me the issue nmonad

Hopefully github does not alter the file, but I cannot guarantee...

kaclark avatar Jun 14 '23 18:06 kaclark

Interesting problem. I think this should be partially possible.

Generally, there's a couple problems. Given the terminal has a lower resolution than a bitmap, for unicode display it is 1px = 1 col, and 1 row = 2px high, whereas with ASCII it's 1px = 2col & 1 px = 1 row. Given that resolution, for a lot of images we receive will be downsized to map to the requested resolution (the API lets you specify the width, and the height is automatically inferred).

Now for ASCII, I can easily imagine how we draw a 100% clear pixel - represent it using spaces, and make sure the colour is reset before (ANSI reset colour code). What isn't so clear, is what should happen in the case of partial transparency. It's not possible to draw semi-transparent colours, so I suspect we'll either have to draw it with colour, or without.

In the case of unicode, the character we use is in the foreground & represents the bottom half of the pixel, so if you need to draw the bottom half as transparent (and the top opaque), you'll need to use the character "Upper Half Block" (https://www.compart.com/en/unicode/U+2580), compared to the Lower Half Block we currently use. Obviously need to be careful in making sure the colours are switched the right way around. :)


If you want to have the behaviour of being able to (not) draw fully transparent pixels, I imagine the best way is to build off the branch in #6, and play around with images with RGBA channels defined (the A channel stands for Alpha, 0 represents 100% transparent, 255 represents 100% opaque). If A = 255 (or perhaps you choose to use some threshold instead, say >= 128), then skip the pixel (i.e. add get_reset_code() and a space to the return string).

I'd try to get the ASCII code method working first (e.g. is_unicode=False), and then look at the unicode method.

That being said, that picture is quite "high resolution", to be perfectly represented in the terminal will take a pretty wide monitor (my Macbook Pro 16" only is ~300 col wide with the font size pretty small), so I'd recommend testing with an image that won't be scaled at all to the width you're displaying at, as downscaling will lead to not-100% alpha channels.

If you're willing to have a crack, or want me to take a look, it's probably a good candidate to include part of the next release (after #6 is merged), as it would technically be a change in behaviour for transparent pictures, if we were to release just with #6.

pnappa avatar Jun 19 '23 00:06 pnappa

Just in case that URL goes dark, here's a copy of the image here (the transparency does indeed exist):

image

pnappa avatar Jun 19 '23 00:06 pnappa

Aha! And this would actually fix an outstanding issue with the image conversion in unicode - if an image is not a multiple of 2px tall, we trim off the remaining pixel. If we add the feature of transparent unicode pixels (using the upper half block glyph), we don't need to do this trim anymore, and can correctly rasterise the final row.

pnappa avatar Jun 19 '23 01:06 pnappa

Hello!

Thank you for this very thorough feedback. I would like to still figure out how to get transparent subsets of images, though I'm fine with waiting for the next patch or so if you think this issue is likely to be fixed soon.

kaclark avatar Jun 20 '23 00:06 kaclark

Sounds good! Let me know if you need any help (first I would recommend working off the add-generic-converter branch) and I can (probably) take a look over the next few days.

Though I should be unavailable this weekend if everything goes to plan 😄.

pnappa avatar Jun 20 '23 01:06 pnappa