Convert a simple picture (e.g. numbers) to bin array

Hi,
(sorry for repeat, I have posted this earlier on a wrong topic)
I am working on a project that captures a small picture (QQVGA 160x120) with an esp32s cam. Target is to have an array (160 x 120 or smaller) with a binary (=b/w) representation of the picture.

So my question is can you please hint me how to covert a small picture to bin array?
Thank you for your guidance!

just for illustration:
|1|1|1|1|0|1|1|1|
|1|1|1|0|0|1|1|1|
|1|1|0|1|0|1|1|1|
|1|1|1|1|0|1|1|1|
|1|1|1|1|0|1|1|1|
|1|1|1|1|0|1|1|1|
|1|1|1|1|0|1|1|1|
|1|1|0|0|0|0|0|1|
image


byte digit1 [] = {
    B11110111,
    B11100111,
    B11010111,
    B11110111,
    B11110111,
    B11110111,
    B11110111,
    B11000001,
};

if you don't care about memory, a 160x120 byte 2D array is the direct answer.
uint8_t image[160][120];
accessing a pixel is straightforward : image[x][y];

If you care about memory, as you are in B&W, you don't need a full byte to represent a pixel, you just need a bit. You could group 8 contiguous pixels in a line or a row (both 160 and 120 can be divided by 8) and use a smaller 2D array
uint8_t image[160][15]; // here grouped 8 bits in the vertical axis
or
uint8_t image[20][120]; // here grouped 8 bits in the horizontal axis
accessing the pixel in position (x,y) requires then a bit more work math. dividing by 8 to find the index, taking the modulo to find the bit and using bitRead() to extract that bit.

thank you! I am going to work with that. Will let you know if I was successful!

There is a great little utility called LCDAssistant. Google it to find.
Basically it will convert a bitmap into a hex array for you.
It might not be exactly what you are looking for, but it might provide an alternative approach to your problem.

I don't think that's what @bigos22 is trying to do, (s)he mentioned capturing a QQVGA 160x120 picture, not designing a custom font for a LCD.

thanks all. btw it is a 'he'. Any help is welcome but indeed I am working on code to convert the pic to bin array. Needs to be within the code not external sw. Thanks!

what is the format of the "pic", isn't it already binary?

what camera do you use? ESP32-CAM with 2MP OV2640? are you getting a QQVGA BMP file format out ?

yes an ESP32-CAM with 2MP OV2640. And yes with some example sw I get via wifi a life QQVGA picture on the laptop.

If you use the BMP format you have direct access to the pixels

If you use jpeg it’s less direct to grab the pixels

Can I control what esp32 is grabbing? Eventually I need an array with bin nr's.
Thanks!

Yes - you can set the camera capture format and grab a frame when you want. Once you have that frame buffer it’s up to you to play with it.

Look at the examples

I meant jpeg or bmp.

yes and no...

At the start of your code you have to define a config variable of type camera_config_t that you'll pass to the initialisation method

esp_err_t err = esp_camera_init(&config);

this is what the structure looks like:

there are two fields of importance for the format:

    pixformat_t pixel_format;       /*!< Format of the pixel data: PIXFORMAT_ + YUV422|GRAYSCALE|RGB565|JPEG  */
    framesize_t frame_size;         /*!< Size of the output image: FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA  */

and those types are defined as such:

typedef enum {
    PIXFORMAT_RGB565,    // 2BPP/RGB565
    PIXFORMAT_YUV422,    // 2BPP/YUV422
    PIXFORMAT_GRAYSCALE, // 1BPP/GRAYSCALE
    PIXFORMAT_JPEG,      // JPEG/COMPRESSED
    PIXFORMAT_RGB888,    // 3BPP/RGB888
    PIXFORMAT_RAW,       // RAW
    PIXFORMAT_RGB444,    // 3BP2P/RGB444
    PIXFORMAT_RGB555,    // 3BP2P/RGB555
} pixformat_t;

typedef enum {
    FRAMESIZE_96X96,    // 96x96
    FRAMESIZE_QQVGA,    // 160x120
    FRAMESIZE_QCIF,     // 176x144
    FRAMESIZE_HQVGA,    // 240x176
    FRAMESIZE_240X240,  // 240x240
    FRAMESIZE_QVGA,     // 320x240
    FRAMESIZE_CIF,      // 400x296
    FRAMESIZE_HVGA,     // 480x320
    FRAMESIZE_VGA,      // 640x480
    FRAMESIZE_SVGA,     // 800x600
    FRAMESIZE_XGA,      // 1024x768
    FRAMESIZE_HD,       // 1280x720
    FRAMESIZE_SXGA,     // 1280x1024
    FRAMESIZE_UXGA,     // 1600x1200
    // 3MP Sensors
    FRAMESIZE_FHD,      // 1920x1080
    FRAMESIZE_P_HD,     //  720x1280
    FRAMESIZE_P_3MP,    //  864x1536
    FRAMESIZE_QXGA,     // 2048x1536
    // 5MP Sensors
    FRAMESIZE_QHD,      // 2560x1440
    FRAMESIZE_WQXGA,    // 2560x1600
    FRAMESIZE_P_FHD,    // 1080x1920
    FRAMESIZE_QSXGA,    // 2560x1920
    FRAMESIZE_INVALID
} framesize_t;

so you would go for FRAMESIZE_QQVGA for the latter but as you can see BMP is not supported for the pixel_format but you have various RGB options

In the description BPP means Bit Per Pixel, so with PIXFORMAT_RGB888 you would get 8 bits (1 byte) for Red, 1 byte for Green and 1 byte for Blue and with PIXFORMAT_GRAYSCALE you would get 1 byte per pixel which would be 256 shades of grey.

Thank you that helps! Is there documentation that I can study on this? Thank you again!

I’m not aware of detailed documentation

There are examples with code samples on line (save to Spiffs etc) and of course source code is the ultimate documentation :slight_smile:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.