cancel
Showing results for 
Search instead for 
Did you mean: 

Bitmap on STM32F746G-DISCO discovery board

Vietvinh Nguyen
Associate III
Posted on April 19, 2017 at 09:29

Hi all

Recently, I created a Win32 application to convert a bitmap (.bmp) file into a header file (.h) in order to display it in mySTM32F746G-DISCO discovery board. Everything works fine but the bitmap (24 bit depth) displays differently (see attached photo) compared to the original bitmap.

0690X00000606oBQAQ.png

Does everyone experience the same? The displayed bitmap seems to be skewed and de-colored. I have done again with a 16-bit-depth bitmap but no further advance.

(I reused the BSP example in STM32CubeF7Packets for the test)

Note: this post was migrated and contained many threaded conversations, some content may be missing.
1 ACCEPTED SOLUTION

Accepted Solutions
Vietvinh Nguyen
Associate III
Posted on April 21, 2017 at 09:31

Yeah! Finally I have resolved the problem:

0690X00000606pnQAA.png

The problem is that there are many formats for a .bmp file. The original bitmap is of 24 bit depth so the LCD driver handled it poor. I changed it to 16 bit, it displayed well (no skew anymore) but with just a few color. I used Photoshop to change it to RGB565 and it is OK.

0690X00000606psQAA.png

Thank you all for kindly help and suggestion.

View solution in original post

25 REPLIES 25
AvaTar
Lead
Posted on April 19, 2017 at 09:47

I don't have a F746-Discover board, but you might want to check that the colour bits from your BMP/ source file end up in the right bits of the display buffer.

Display drivers tend to support different colour depth modes, so some bit masking and shift will be involved.

Recently, I created a Win32 application to convert a bitmap (.bmp) file into a header file (.h) ...

GIMP (the Gnu Image Manipulation Program), available for Windows as well, supports export of images to

*.h

files.

No need to re-invent the wheel ...

Posted on April 19, 2017 at 09:58

Thanks for your reply.

I converted the entire .bmp file where the header contains all information about the index, width, height and bit-depth. I also found that the LCD driver has mechanism to check it. Something likes below:

/**   * @brief  Draws a bitmap picture loaded in the internal Flash in ARGB888 format (32 bits per pixel).   * @param  Xpos: Bmp X position in the LCD   * @param  Ypos: Bmp Y position in the LCD   * @param  pbmp: Pointer to Bmp picture address in the internal Flash   * @retval None   */ void BSP_LCD_DrawBitmap(uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp) {   uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;   uint32_t address;   uint32_t input_color_mode = 0;      /* Get bitmap data address offset */   index = *(__IO uint16_t *) (pbmp + 10);   index |= (*(__IO uint16_t *) (pbmp + 12)) << 16;      /* Read bitmap width */   width = *(uint16_t *) (pbmp + 18);   width |= (*(uint16_t *) (pbmp + 20)) << 16;      /* Read bitmap height */   height = *(uint16_t *) (pbmp + 22);   height |= (*(uint16_t *) (pbmp + 24)) << 16;       /* Read bit/pixel */   bit_pixel = *(uint16_t *) (pbmp + 28);         /* Set the address */   //address = hLtdcHandler.LayerCfg[ActiveLayer].FBStartAdress + (((BSP_LCD_GetXSize()*Ypos) + Xpos)*(4));   address = hLtdcHandler.LayerCfg[ActiveLayer].FBStartAdress + (((BSP_LCD_GetXSize()*Ypos) + Xpos)*(4));      /* Get the layer pixel format */       if ((bit_pixel/8) == 4)   {     input_color_mode = CM_ARGB8888;   }   else if ((bit_pixel/8) == 2)   {     input_color_mode = CM_RGB565;      }   else    {     input_color_mode = CM_RGB888;   }      /* Bypass the bitmap header */   pbmp += (index + (width * (height - 1) * (bit_pixel/8)));        /* Convert picture to ARGB8888 pixel format */   for(index=0; index < height; index++)   {     /* Pixel format conversion */     LL_ConvertLineToARGB8888((uint32_t *)pbmp, (uint32_t *)address, width, input_color_mode);          /* Increment the source and destination buffers */     address+=  (BSP_LCD_GetXSize()*4);     pbmp -= width*(bit_pixel/8);   }  }

Posted on April 19, 2017 at 10:07

AvaTar wrote:

...

GIMP (the Gnu Image Manipulation Program), available for Windows as well, supports export of images to

*.h

files.

No need to re-invent the wheel ...

I've already used GIMP but the output files it exports are not as what I expected.  The expected format is as bellow:

0690X00000602SGQAY.bmp

But GIMP produces it differently:

0690X00000602S1QAI.bmp

Do you have any hint for me?

Posted on April 19, 2017 at 10:40

As said, I neither have a F746 disco, nor do I use Cube code. I draw from experiences with other boards/LCD drivers and SPL library code.

I also found that the LCD driver has mechanism to check it. Something likes below: ...

Is this function aware of the current colour mode of the LCD driver ?

This mode is usually set during initalization in some config register.

LCD driver ICs I dealt with also supported BW, 8-bit, 16-bit and 18-bit modes.

The image seen on your initial post seems to have bits end up in the wrong colour.

Posted on April 19, 2017 at 11:02

Do you have any hint for me?

Not really.

Don't know your exact requirements, writing a new app might be less expensive than adapting the GIMP output.

If it works so far, there is no reason to change it.

Posted on April 19, 2017 at 11:12

I think the function can recognize the current colour mode of the LCD because as you see below:

...

/* Get the layer pixel format */

 

if ((bit_pixel/8) == 4)

 

{

 

input_color_mode = CM_ARGB8888;

 

}

 

else if ((bit_pixel/8) == 2)

 

{

 

input_color_mode = CM_RGB565;

 

}

 

else

 

{

 

input_color_mode = CM_RGB888;

 

}

 

 

/* Bypass the bitmap header */

 

pbmp += (index + (width * (height - 1) * (bit_pixel/8)));

 

 

/* Convert picture to ARGB8888 pixel format */

 

for(index=0; index < height; index++)

 

{

 

/* Pixel format conversion */

 

LL_ConvertLineToARGB8888((uint32_t *)pbmp, (uint32_t *)address, width, input_color_mode);

 

 

/* Increment the source and destination buffers */

 

address+= (BSP_LCD_GetXSize()*4);

 

pbmp -= width*(bit_pixel/8);

 

}

...

It can process

32

-bit-color bitmap (CM_ARGB8888

), 16-bit-color bitmap (CM_RGB565) and other (CM_RGB888). Finally, it convert all to ARGB8888 by calling the function LL_ConvertLineToARGB8888((uint32_t *)pbmp, (uint32_t *)address, width, input_color_mode);The driver for the LCD is so complicated so I have not yet studied it further. I just try to use it first.
Posted on April 19, 2017 at 11:36

The bitmap-displaying function in the STM32Cube for the discovery board can display bitmap files directly from uSD card, no need any conversion. That is an advantage. However, before I test it, I would like to display bitmaps from RAM first. So I need to move the bitmaps to RAM by converting it to header file. Then the problem appeared so I am here to ask. Hoping that someone who experienced the same would help. You know, reading and displaying bitmaps directly from uSD card would be great, especially if you want to create a tiny webserver or HMI.

Posted on April 19, 2017 at 11:50

That might point to an endianess issue with your code.

I don't know the Cube code involving SD card file reads, but I expect it to pull the values byte wise, thus avoiding endianess problems.

Posted on April 19, 2017 at 11:59

OK, thanks, let me try to revise my conversion app with endianess changing form bigendian to littleendian and vice verse, then I will test it again tomorrow. Thank you very much for your time. Hope to see you tomorrow.