mrcodetastic / ESP32-HUB75-MatrixPanel-DMA

An Adafruit GFX Compatible Library for the ESP32, ESP32-S2, ESP32-S3 to drive HUB75 LED matrix panels using DMA for high refresh rates. Supports panel chaining.
MIT License
970 stars 211 forks source link

Unusable gif in bits 2 #137

Closed tsctrl closed 3 years ago

tsctrl commented 3 years ago

hi @mrfaptastic ,

back to old test using nyan cat image. gif look very bad with PIXEL_COLOR DEPTH_BITS 2 background color blue becoming black in the display. basically is unusable to play gif in bits 2. the gif are already rendered with 8 bits color pallet which the lowest i can go to generate the gif which only consist 8 color. please find attached gif i used for the test. no issue with bits 3 however the gif rendered properly. i think lowest bit 2 should also be able to render 8 color tables at least.

it there any can be improve on the library to allow lower bit depth as low as the lowest 2? of should i use other gif generator to convert the image?

nyan gif pallets

thanks in advanced

mrcodetastic commented 3 years ago

Hello. Running the library with a colour depth != 8 is not something that can be relied on as it's undefined what the real colour palette will be available. Also, not all 2bit colour palettes are the same hence potential missing colours.

Do you really need to run the library at 2 bit colour? 4 bit would be the minimum I think, at least from my testing before things became horrible.

tsctrl commented 3 years ago

ya, for 192x64 i can set to 2. 3 wifi not working, 4 i will have guru meditation error. run out of option. tried to add psram to my modules today but still no success. wondering is there is workaround such as gif converter or conversion technic that can properly map the color that match the bits supported. or potentially map the bit to the closest bit for that color.

what i did not understand is why the matrix can run 8bit 255 variation for each channel but couldnt get matching color pallets. i am guessing the AnimatedGif example did not properly match the palette and the 8 bit pixels.

edit: do the 2bit color makes the color selection become undefined per 1:1 match?. able match to closes lower bits would be great to have. i am able to do full range 255 8bit running in 2 bits. so wondering why couldnt get matching pallets. understand that color pallets 8 color above does not to be exact match with the 2 bit color.

mrcodetastic commented 3 years ago

I'm not sure.

Looks like there's some obsure color bit-match issue which exposes itself when you're using such a low color depth. This isn't a graphics library, it's a 8bit colour -> DMA LED PWM library essentially.

Best bet is to play with the library directly using drawPixel and see what color values do work at such a low color depth and check that the gif is using the right color.

tsctrl commented 3 years ago

look like convert images to gif is a must and creating new gif images that support 2 bits color is not an option. i have no control what is the resulting color bits. the only option left now is by reducing the ram usage and increase the bits to at least 4.

mbedTLS and wifi consume lots of memory even after optimization. not sure if i could get those lesser.

vortigont commented 3 years ago

this won't work by design. 2 bit gif actually means "Take any four colors out of 256, put it into an index table and encode whole image using only those 4 colors". So, when decoded, you will receive the same 8 bit depth color image, but with only 4 different colors. 2 bit depth in this lib actually means using 2 most significant bits per each color and throw away the rest, which results in 6 bits total or 64 colors. There is no need to reduce color index depth in GIFs, once decoded you will receive 8 bit depth anyway. It only helps to reduce gif file size, not color depth.

tsctrl commented 3 years ago

logically, 64 colors or 2 bits should be enough to render 8 color gif even it is from any range of 255 colors. right?

gif export that i did only work up to 8 color gif no less. 4 color gif looks garbage. agree with the 8 bit depth gif, instead of using full 255 range color. the gif export reduce the color up to 8 color but any from the 255 range.

the issue is the lib cant map this 8 color gif to 64 color. look like the lib already have those 64 color selection in place(no issue). throw any color that not supported (issue). logically if we can key in any 255 range in two bits the lib can convert it to nearest color from 64 color which what the lib is doing now.

if 8 color gif are still 255 color read by the library. no way we can properly create gif with 64 exact color that can be accepted by lib and 255 is what range that the lib can accept btw even in 2 bits mode.

the animated gif is properly map to color 565, still in 255 range no issue there too..

vortigont commented 3 years ago

logically, 64 colors or 2 bits should be enough to render 8 color gif even it is from any range of 255 colors. right?

No, absolutely not! Consider GIF as just a palette - you have full 24 bit RGB colors, choose any 256 (or less, up to two) colors and store in your palette. Need a nice blue sky gradient - choose 256 blue colors from dark to light and draw your sky. Need a chess board with Ivory and dark blue - take 2 of those colors. But to draw it you still need True Color 24 capable device (8 bit x RGB in this lib). Once you start reducing lib's color depth less than 8 you will never be able to draw exact same colors even from a 2 bit gif (well, except pure black and white maybe) :)

tsctrl commented 3 years ago

never be able to draw exact same colors even from a 2 bit gif

never be able to draw 'exact' colors is yes, but the result of gif blue background becoming black in the panel. and not blue. but why i can use color565(0,0,255) to draw a blue text? or even color565(0,255,255) to have a light blue?

i am looking at neocat example here how he did the hsv conversion. i guess this something related and yes i totally did not understand what the code is doing.

edit: 8pallets i might have lesser than 2 bits capability of matching the colors, but yes i can guess this 8 pallets to respective 444 or 565 color but why the library dont. but ya, the blue background are almost black..

i think i have simple solution for this, but not really the real solution i guess. i would need to reassign the 565 value that was set by the gif animator to the more nearest value of 64 color that was supported by the library in 2 bits. means i have to divide the 565 value that was set by the gif animator to 255 then reassign to the nearest preset value so i can control the colors of any gif.

tsctrl commented 3 years ago

this is another result, i am using PIXEL_COLOR_DEPTH_BITS 3. it is a panda head panda-panel

from this true color image: panda

mrcodetastic commented 3 years ago

i think i have simple solution for this, but not really the real solution i guess. i would need to reassign the 565 value that was set by the gif animator to the more nearest value of 64 color that was supported by the library in 2 bits. means i have to divide the 565 value that was set by the gif animator to 255 then reassign to the nearest preset value so i can control the colors of any gif.

Yep. You need to write some color mapping code in the drawgif function.

tsctrl commented 3 years ago

look like it simply change unknown color to black

mrcodetastic commented 3 years ago

This isn't a problem with this library. You're simply not going to get magical colors from an ESP32 with that many panels, double buffering etc.

2 bits per sub pixel = only FOUR possible brightness values per color channel. Horrible color reproduction even if you did match things up.

Uncomment line 87 of ESP32-HUB75-MatrixPanel-I2S-DMA.h as well to turn off CIE1931 for such a low color depth.

// #define NO_CIE1931

make it

#define NO_CIE1931

For example, using a blue color only, with 2bit color per color subpixel:

255/4 = 1-64 = black, 64-127 = 25%, 127-192 = 75%, 192+ 100% brightness

That's what I see with a simple arduino sketch.


uint8_t wheelval = 0;
void loop() {

    dma_display.fillScreenRGB888(0,0,wheelval);

    wheelval++;
    delay(50); 
    Serial.print("Value is:");
    Serial.println(wheelval);

}
tsctrl commented 3 years ago

pallet-1 panel-2

problem with rendering gray or near to black color. will try that @mrfaptastic

thanks!

mrcodetastic commented 3 years ago

Again, not a problem with this library.

2-bits-per-pixel = 6 bits color palette (given there are three colors)

https://lospec.com/palette-list/6-bit-rgb

mrcodetastic commented 3 years ago

Using paint.net to see what your original 8bitpp color image would look like @2bitpp:

image

Actually looks worse than what the LED matrix outputs.

tsctrl commented 3 years ago

hi @mrfaptastic

disable the cie 1931 make the color a bit more sense, but on the higher bits turning on cie 1931 is better. but still the color are now more white like brightness. if i want to change the brightness effected by the cie1931 or might change the white or black level how can i do that?

255/4 = 1-64 = black, 64-127 = 25%, 127-192 = 75%, 192+ 100% brightness

this is the calculation i need for conversion or the library is actually doing this in 2 bits? thanks for the 64 color pallets!

thanks!

tsctrl commented 3 years ago

understood, thats the range applied for 2 bit depth

thanks @mrfaptastic