I want to create HBITMAP from byte array with JPEG format.
I have searched but I only can create it from bitmap file as
HBITMAP hbm = (HBITMAP)LoadImage(NULL,"fileName",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
Can someone show me how to do it?
Just use GDIplus.
It supports loading JPEGs, and some other stuff feels much more logically
http://msdn.microsoft.com/en-us/library/ms533830%28v=vs.85%29.aspx
Use "Bitmap" class.
When you have the jpeg in a buffer, you need to read it by a stream.
MFC provides a CImage
class that wraps a bitmap object. It provides convenience methods to load and save images in a host of formats, including JPEG, GIF, BMP, and PNG.
So the first order of business is obtaining a CImage
object representing your HBITMAP
. You can do this by calling the Attach
method and passing the handle.
But in this case, it looks like you can skip that entirely and just have the CImage
object load your image from the file directly. Use the Load
method for that.
Once you've got a CImage
object representing your image, just call the Save
method and specify the desired file name with the appropriate extension. According to the documentation:
If the guidFileType
parameter is not included, the file name's file extension will be used to determine the image format. If no extension is provided, the image will be saved in BMP format.
Sample code:
CImage img;
img.Load(TEXT("fileName.bmp")); // load a bitmap (BMP)
img.Save(TEXT("fileName.jpg")); // and save as a JPEG (JPG)
You can also reverse this pattern, using the Load
method to load JPEG files and the Save
method to save BMP files.
I found the following code //http://katahiromz.web.fc2.com/win32/loadjpeg.html
The red and blue were swapped, so here is a corrected version with the colours corrected. It uses jpeglib, so you must first compile that. If you need only to convert a buffer, then you can skip the line that loads the file - the details of converting should be the same.
extern "C" {
#include <jpeglib.h>
#include <jerror.h>
}
#pragma comment(lib, "jpeg.lib")
HBITMAP LoadJpegAsBitmap(const std::string & filename)
{
struct jpeg_decompress_struct decomp{};
struct jpeg_error_mgr jerror{};
BITMAPINFO bi = {};
LPBYTE lpBuf, pb = NULL;
HBITMAP hbm{};
JSAMPARRAY buffer{};
INT row = 0;
decomp.err = jpeg_std_error(&jerror);
jpeg_create_decompress(&decomp);
FILE* file = fopen(filename.c_str(), "rb");
if (file == nullptr)
{
return NULL;
}
jpeg_stdio_src(&decomp, file);
jpeg_read_header(&decomp, TRUE); // read jpeg file header
jpeg_start_decompress(&decomp); // decompress the file
row = ((decomp.output_width * 3 + 3) & ~3);
buffer = (*decomp.mem->alloc_sarray)((j_common_ptr)&decomp, JPOOL_IMAGE,
row, 1);
ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = decomp.output_width;
bi.bmiHeader.biHeight = decomp.output_height;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 24;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = row * decomp.output_height;
hbm = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**)&lpBuf, NULL, 0);
if (hbm == NULL)
{
jpeg_destroy_decompress(&decomp);
fclose(file);
return NULL;
}
pb = lpBuf + row * decomp.output_height;
while (decomp.output_scanline < decomp.output_height)
{
pb -= row;
jpeg_read_scanlines(&decomp, buffer, 1);
if (decomp.out_color_components == 1)
{
UINT i;
LPBYTE p = (LPBYTE)buffer[0];
for (i = 0; i < decomp.output_width; i++)
{
pb[3 * i + 0] = p[i];
pb[3 * i + 1] = p[i];
pb[3 * i + 2] = p[i];
}
}
else if (decomp.out_color_components == 3)
{
// There was talk on Internet about one being RGB and another BGR.
// If colors appear swapped, then swap the bytes, and update this comment.
//CopyMemory(pb, buffer[0], row);
// Updated color correction
UINT i;
LPBYTE p = (LPBYTE)buffer[0];
for (i = 0; i < row; i += 3)
{
pb[i + 0] = p[i + 2]; // Blue
pb[i + 1] = p[i + 1]; // Green
pb[i +2] = p[i + 0]; // Red
}
}
else
{
jpeg_destroy_decompress(&decomp);
fclose(file);
DeleteObject(hbm);
return NULL;
}
}
SetDIBits(NULL, hbm, 0, decomp.output_height, lpBuf, &bi, DIB_RGB_COLORS);
jpeg_finish_decompress(&decomp);
jpeg_destroy_decompress(&decomp);
fclose(file);
return hbm;
}