Bodmer / JPEGDecoder

A JPEG decoder library
Other
220 stars 64 forks source link

Swap Colors #57

Closed codingiscodlike closed 3 years ago

codingiscodlike commented 3 years ago

Hi thank you for this Lib! It works very good with ESP32 and SD Card. I have the TFT 128x160p - ST7735 (Blue PCB) and it seems like red and blue color is swapped. Is it possible to swap those colors them during the render Process ?

codingiscodlike commented 3 years ago

I tried this but getting a compiler error:

invalid conversion from 'int' to 'uint16_t {aka short unsigned int}' [-fpermissive]

maybe you could help ??

uint16_t *pImg; ...

if ( ( mcu_x + win_w) <= tft.width() && ( mcu_y + win_h) <= tft.height()) { tft.drawRGBBitmap(mcu_x, mcu_y, swap2colors(pImg), win_w, win_h); }

uint16_t swap2colors(uint16_t color){ uint16_t r = color & 31; //B000000000011111 uint16_t g = color & 992; //B000001111100000; uint16_t *b = color & 31744; //B111110000000000; r = r << 10; b = b >> 10; color = r & g & b; return color; }

Bodmer commented 3 years ago

This is probably swapped bytes not swapped colours. If drawing something direct to screen in a red colour works fine then the problem is swapped bytes. If you are using the TFT_eSPI graphics library then you can use. tft.setSwapBytes(true); in setup(). You can reset the byte swapping to the default setting with: tft.setSwapBytes(false);

kriv0lap0v commented 3 years ago

Try to remove "" in each of "uint16_t ". This way you declare a pointer to uint16_t-variable but you mean the variable itself.

Bodmer commented 3 years ago

@kriv0lap0v That will not work, there are many faults in the code segment because pImg is a pointer to an array fo colour values, so every colour in that array would need to be swapped. As indicated above the problem is likely to be swapped bytes (due to different endianess). Some grpahics libraries provide a switch to handle this.

kriv0lap0v commented 3 years ago

Yes, you are right. I thought the code is going to swap color bits in a single pixels. It is necessary to run a cycle over all the pixel buffer and swap each of the pixels. Anyway, it is not correct to apply bitwise operations to the pointer, isn't it? :)

Bodmer commented 3 years ago

On the assumption you are using Adafruit_GFX with the example sketch, then the simplest solution is to replace this line, with:

  while ( JpegDec.readSwappedBytes()) {

This will not work if your TFT is not displaying the correct colours with simple graphics commands like fillRect, in that case the driver for the TFT is not setup correctly.

codingiscodlike commented 3 years ago

Thank you all for your answers. I am using the Adafruit_GFX.

while ( JpegDec.readSwappedBytes()) {

This didn't realy help. Now the images look more strange than before :-)

Bodmer commented 3 years ago

Does using fillRect to draw a filled rectangle a red colour show the right colour?

codingiscodlike commented 3 years ago

No, thats what i tried to tell you. The Red and Blue is completly swapped :-) so i need to swap it for each pixel on every output.

Bodmer commented 3 years ago

In that case you need to select the right driver for your TFT. You can have two problems:

  1. byte swapping - shown not to be the case
  2. wrong TFT configuration

There is a registerin the TFT controller that has a bit that controls the colour order, at the moment that bit is in the wrong state.

Which Adafruit_GFX support library are you using? Post a link to the ST7735 library you are using and I will tell you which line to change.

Bodmer commented 3 years ago

A library bodge would be to change these lines, to read:

            const uint8_t *pSrcB = image_info.m_pMCUBufR + src_ofs;
            const uint8_t *pSrcG = image_info.m_pMCUBufG + src_ofs;
            const uint8_t *pSrcR = image_info.m_pMCUBufB + src_ofs;

This swaps the red and blue but really you ought to fix the driver initialisation code as I suggest above.

codingiscodlike commented 3 years ago

i am using this display: https://www.ebay.de/itm/1-8-zoll-128X160-SPI-ST7735S-TFT-LCD-Vollfarbdisplay-Modul-STM32-C51-fur-Arduino/233628449870?hash=item3665573c4e:g:mF8AAOSw9CNe8tAC

And these two libs:

include

include

This was the only which worked only the Red and Blue is swaped...

tft.initR(INITR_GREENTAB); // Init ST7735S chip, green tab

Yeah I also think it would be the best to fix the driver instead of destroying the other libs :-)

codingiscodlike commented 3 years ago

A library bodge would be to change these lines, to read:

          const uint8_t *pSrcB = image_info.m_pMCUBufR + src_ofs;
          const uint8_t *pSrcG = image_info.m_pMCUBufG + src_ofs;
          const uint8_t *pSrcR = image_info.m_pMCUBufB + src_ofs;

This swaps the red and blue but really you ought to fix the driver initialisation code as I suggest above.

But i will give this a try tomorrow, this is challenging me :-)

codingiscodlike commented 3 years ago

this is the Lib I used https://github.com/adafruit/Adafruit-ST7735-Library

Bodmer commented 3 years ago

In the Adafruit ST7735 library alter this line in Adafruit_ST7735.h to:

#define ST7735_MADCTL_BGR 0x00

and this line in Adafruit_ST77xx.h to:

#define ST77XX_MADCTL_RGB 0x08

Upload the sketch again to your board and that should correct the colours.

codingiscodlike commented 3 years ago

this worked out...

  const uint8_t *pSrcB = image_info.m_pMCUBufR + src_ofs;
  const uint8_t *pSrcG = image_info.m_pMCUBufG + src_ofs;
  const uint8_t *pSrcR = image_info.m_pMCUBufB + src_ofs; 

I will try to setup the driver next ...

codingiscodlike commented 3 years ago

In the Adafruit ST7735 library alter this line in Adafruit_ST7735.h to:

#define ST7735_MADCTL_BGR 0x00

and this line in Adafruit_ST77xx.h to:

#define ST77XX_MADCTL_RGB 0x08

Upload the sketch again to your board and that should correct the colours.

This worked out perfectly! Thank you very much