There appear to be three different functions for converting from a JPEG Frame Buffer to a buffer containing BITMAP data, but try as I might I cannot find any documentation on any of them. There's an example that I came across that uses frame2bmp, but even in the example there's no information on its limitations (e.g. it generally can't handle frame sizes above SVGA).
Ideally I'd appreciate it if someone could point me to actual, comprehensive descriptions of those three functions.
But barring that, could someone tell me what KIND of bitmap they each create? The fmt2tgb888 pretty clearly creates rgb888 pixels. But what do the other two do? In fact, there appears to be SEVERAL bmp formats:
PIXFORMAT_RGB565, // 2BPP/RGB565
PIXFORMAT_RGB888, // 3BPP/RGB888
PIXFORMAT_RGB444, // 3BP2P/RGB444
PIXFORMAT_RGB555, // 3BP2P/RGB555
Also, importantly, when you get the resultant bitmap data in its own buffer, is it ONLY the pixel data? Or does it also include the necessary bitmap format HEADER data so that the buffer could then be sent out to a file?
I've discovered that if you create a Frame Buffer containing PIXFORMAT_JPEG you can just send that out to a file and the file is indeed a valid JPEG file, which pretty clearly indicates that the Frame Buffer contains not just the pixel data but also the necessary HEADER info. Not so if you load any of the RGB formats directly into the FrameBuffer. All you get in that case is the pixel data, no header info. If you try to save that kind of Frame Buffer out to a file you end up with an invalid image file.
fmt2rgb888 OR fmt2bmp OR frame2bmp
-
- Posts: 1
- Joined: Fri Apr 23, 2021 4:23 pm
Re: fmt2rgb888 OR fmt2bmp OR frame2bmp
I found a "wasteful" way to convert the JPEG format to any other BMP format.
You see, as you pointed out, there is a pretty simple way to convert from JPEG to RGB888.
Well, from there, you can make your own converter from RGB888 to RGB-whatever!
On git hub (https://github.com/espressif/esp32-came ... bmp.c#L190), you can see that they themselves already built a converter from RGB565 to RGB888.
Nice, right? Now, we just need to undo that!
Beware that when you use this function, the memory allocated to the buffer hasn't changed; we merely changed how bits are represented in the array.
I call this a "wasteful" solution because, instead of directly transferring the JPEG format to what we want, we are first transferring the JPEG to RGB888, and then RGB888 to RGB565.
Note that even if the memory allocated to the array is the same, the useful size of the newly converted array is 2/3 of what it was, because we are now using 2 bytes to represent colors instead of 3 bytes.
If you want to convert back the rgb565 to rgb888, you can, but you need to be aware that:
- this process of converting is quite resource consuming for a microcontroller (about 76'800 loops for the QVGA format, for example).
- when you create a converter function that takes a smaller format, and transfers it to a bigger one *directly in the same array it is stored in before the conversion*, make sure you set the indexes of the array in reverse order. Else, you are going to run into (in my opinion) very cool but undesirable data corruption problems (you won't break anything, but your pixels won't have the color they had before . Actually, it might be fun to try out for yourself!).
And there you go. Hope I helped!
You see, as you pointed out, there is a pretty simple way to convert from JPEG to RGB888.
Well, from there, you can make your own converter from RGB888 to RGB-whatever!
On git hub (https://github.com/espressif/esp32-came ... bmp.c#L190), you can see that they themselves already built a converter from RGB565 to RGB888.
Nice, right? Now, we just need to undo that!
Code: Select all
bool rgb888ToRgb565(const uint8_t *src_buf, size_t src_len)
{
unsigned int red;
unsigned int green;
unsigned int blue;
unsigned long bufferIndex = 0;
for(unsigned long i = 0; i < src_len; i++)
{
bufferIndex = i*3;
red = src_buf[bufferIndex];
green = src_buf[bufferIndex + 1];
blue = src_buf[bufferIndex + 2];
((unsigned int*)src_buf)[i] =
((red & 0xF8) << 8)
| ((green & 0xFC) << 3)
| ((blue & 0xF8) >> 3);
}
}
I call this a "wasteful" solution because, instead of directly transferring the JPEG format to what we want, we are first transferring the JPEG to RGB888, and then RGB888 to RGB565.
Note that even if the memory allocated to the array is the same, the useful size of the newly converted array is 2/3 of what it was, because we are now using 2 bytes to represent colors instead of 3 bytes.
If you want to convert back the rgb565 to rgb888, you can, but you need to be aware that:
- this process of converting is quite resource consuming for a microcontroller (about 76'800 loops for the QVGA format, for example).
- when you create a converter function that takes a smaller format, and transfers it to a bigger one *directly in the same array it is stored in before the conversion*, make sure you set the indexes of the array in reverse order. Else, you are going to run into (in my opinion) very cool but undesirable data corruption problems (you won't break anything, but your pixels won't have the color they had before . Actually, it might be fun to try out for yourself!).
And there you go. Hope I helped!
Who is online
Users browsing this forum: No registered users and 27 guests