[SOLVED] Efficient way to draw bitmap using array of pixel data

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • [SOLVED] Efficient way to draw bitmap using array of pixel data

    Recently, I was stuck with drawing bitmap using array of pixel data.

    The scenario is like:
    The image size is 320 x 240.
    The array is something like uint32_t array[320*240].
    All pixel data is 32-bit with RGB888.
    The LCD works at GUICC_M565.
    As a test, I drew the image pixel by pixel as follows:

    C Source Code

    1. uint32_t c, r;
    2. uint32_t * ibPtr = array;
    3. for (r = 0; r < 240; r++)
    4. {
    5. for (c = 0; c < 320; c++)
    6. {
    7. GUI_SetColor (*ibPtr);
    8. GUI_DrawPixel (c, r);
    9. ibPtr++;
    10. }
    11. }
    Display All

    The result was right, but too slow.
    My question is: is there an efficient way to accomplish that?
    I read UM03001 over and over again with no answer.

    The post was edited 1 time, last by kenmux ().

  • Hi kenmux,

    Consider the following:

    Dont let emWin draw each of the 76800 Pixel one by one when you want to diplay a bitmap.
    The best way is to use the emWin "Bitmap Drawing" routines.
    Look at chapter 8.1.4. and start e.g. with GUI_DrawBitmap().

    You have to adapt your bitmap array to the needs of GUI_DrawBitmap() paramter definition.
    An easy way to bild the bitmap is to use the Segger Bitmap Converter (see chapter 10):
    Load any kind of picture / bitmap file
    "Save As..." C-File and choose emWin color format (e.g. 565).
    You will get an bitmap array.
    This array you can directly use with GUI_DrawBitmap.
    Quite simple and fast.

    For a good performance: define the bitmaparray in the same color format your hardware is using, e.g. 565.
    Otherwise emWin has to do a colorconversion for each(!) pixel (shifting bits back and forth). This comsumes a lot of processing power.
    See hint in the documentation under 10.6.5:

    "Further it is strongly recommended to save the C files in the exact same format used
    by the hardware. Note that using the right format will have a positive effect on the
    drawing performance. If a high color bitmap for example should be shown on a sys-
    tem with a color depth of 16bpp which has the red and blue components swapped,
    the best format is ’High color 565, red and blue swapped’. Already a slightly other
    format has the effect, that each pixel needs color conversion, whereas a bitmap in
    the right format can be rendered very fast without color conversion. The difference of
    drawing performance in this case can be factor 10 and more."


    Hope this helps.
    Matz
  • Hi XT-Matz,
    Thanks for your reply! Your idea is bright & helpful.

    An easy way to bild the bitmap is to use the Segger Bitmap Converter (see chapter 10):
    Load any kind of picture / bitmap file
    "Save As..." C-File and choose emWin color format (e.g. 565).
    Yep. The data is generated from a camera and stored in RAM. So, this is impossible.

    Dont let emWin draw each of the 76800 Pixel one by one when you want to diplay a bitmap.
    The best way is to use the emWin "Bitmap Drawing" routines.
    Look at chapter 8.1.4. and start e.g. with GUI_DrawBitmap().
    This idea is good, and the problem is how to struct a bitmap using the pixel data (complicated but feasible).
    Also, memory block copy may be involved (not very efficient).

    So, is there any way to tell emWin how to fetch the pixel data in the array without bitmap header & info header?

    The post was edited 1 time, last by kenmux ().

  • Hi kenmux,
    data is generated from a camera and stored in RAM
    OK. With this new information my idea was a dog's breakfast...

    I dont know wether it will work, but one idea could be:

    GUI_DrawBitmap() needs a pointer to a GUI_BITMAP struct, containing all information needed: Sizes, BytesPerLine, BitsPerPixel,color Format, pointer to the bitmap.
    Put into such a GUI_BITMAP structure all information about the arrangement of your graphic memory data.
    A sample structure could be something like that:

    Source Code

    1. GUI_CONST_STORAGE GUI_BITMAP bmgraphicmemory = {
    2. 320, // xSize
    3. 240, // ySize
    4. 960, // BytesPerLine
    5. 24, // BitsPerPixel
    6. (unsigned char *)_pgraphicmemory, // Pointer to picture data
    7. NULL, // Pointer to palette
    8. GUI_DRAW_BMP24
    9. };
    10. void GUI_DrawBitmap(bmgraphicmemory , 0, 0);
    Display All

    Please compare to chapter 8.1.4 and 8.1.5!

    In the worst case if your bitmap data in memory is arranged in a way which is not supported by GUI_DrawBitmap (see 8.1.5), you may have to rearrange it previously. If you are limited with memory - who is not? - you must do it in multiple smaller portions.

    I can imagine that this way will be much faster, than DrawPixel one by one.

    Its only an idea. Dont hit me if it dont work, because I'm also a emWin beginner. But maybe the idea is helpful to you.

    Regards.
    XT-Matz
  • Hi XT-Matz,

    OK. With this new information my idea was a dog's breakfast...
    Take it easy, man. Your idea is feasible & helpful anyhow.

    GUI_DrawBitmap() needs a pointer to a GUI_BITMAP struct, containing all information needed: Sizes, BytesPerLine, BitsPerPixel,color Format, pointer to the bitmap.
    Put into such a GUI_BITMAP structure all information about the arrangement of your graphic memory data.
    The idea is great! And I tested with the code showed below:

    C Source Code

    1. GUI_BITMAP bitmap = {0};
    2. bitmap.XSize = 320;
    3. bitmap.YSize = 240;
    4. bitmap.BytesPerLine = 1280;
    5. bitmap.BitsPerPixel = 32;
    6. bitmap.pData = (const uint8_t *)array;
    7. bitmap.pPal = NULL;
    8. bitmap.pMethods = GUI_DRAW_BMP8888;
    9. GUI_DrawBitmap (&bitmap, 0, 0);


    The result was right except the red and blue swapped.
    And to my surprise, there's no method api called 'GUI_DRAW_BMPM8888'!
    So I tried to convert the data pixel by pixel and use GUI_DRAW_BMPM565 instead.
    Hmm, it was not sound that efficient, but acceptable.

    Thanks. You saved me!