C++ 从jpeg内存缓冲区创建HBITMAP?
我想用JPEG格式从字节数组创建HBITMAP 我已经搜索过了,但我只能从位图文件创建它C++ 从jpeg内存缓冲区创建HBITMAP?,c++,windows,winapi,mfc,hbitmap,C++,Windows,Winapi,Mfc,Hbitmap,我想用JPEG格式从字节数组创建HBITMAP 我已经搜索过了,但我只能从位图文件创建它 HBITMAP hbm = (HBITMAP)LoadImage(NULL,"fileName",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION); 有人能告诉我怎么做吗?只要使用GDIplus就行了。 它支持加载JPEG,其他一些东西感觉更符合逻辑 使用“位图”类。 当缓冲区中有jpeg时,您需要通过流来读取它。MFC提供了一种包装位图对象的方
HBITMAP hbm = (HBITMAP)LoadImage(NULL,"fileName",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
有人能告诉我怎么做吗?只要使用GDIplus就行了。
它支持加载JPEG,其他一些东西感觉更符合逻辑
使用“位图”类。
当缓冲区中有jpeg时,您需要通过流来读取它。MFC提供了一种包装位图对象的方法。它提供了以多种格式加载和保存图像的便捷方法,包括JPEG、GIF、BMP和PNG
因此,业务的第一个顺序是获取一个表示您的HBITMAP
的CImage
对象。您可以通过调用并传递句柄来实现这一点
但是在这种情况下,看起来您可以完全跳过它,直接让CImage
对象从文件中加载图像。用这个
一旦获得了表示图像的CImage
对象,只需调用Save
方法并指定所需的文件名和相应的扩展名。根据文件:
如果未包含guidFileType
参数,则将使用文件名的文件扩展名来确定图像格式。如果未提供扩展名,图像将以BMP格式保存
示例代码:
CImage img;
img.Load(TEXT("fileName.bmp")); // load a bitmap (BMP)
img.Save(TEXT("fileName.jpg")); // and save as a JPEG (JPG)
您还可以反转此模式,使用
Load
方法加载JPEG文件,使用Save
方法保存BMP文件//
红色和蓝色被交换了,所以这里是一个修正版,颜色也被修正了。它使用jpeglib,所以您必须首先编译它。如果只需要转换缓冲区,则可以跳过加载文件的行-转换的详细信息应相同
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;
}
extern“C”{
#包括
#包括
}
#pragma注释(lib,“jpeg.lib”)
HBITMAP加载JPEGASBitmap(常量std::字符串和文件名)
{
结构jpeg_decompress_struct decomp{};
结构jpeg_error_mgr jerror{};
BITMAPINFO bi={};
LPBYTE lpBuf,pb=NULL;
HBITMAP hbm{};
JSAMPARRAY缓冲区{};
INT行=0;
decomp.err=jpeg\u std\u error(&jerror);
jpeg\u创建\u解压缩(&decomp);
FILE*FILE=fopen(filename.c_str(),“rb”);
if(file==nullptr)
{
返回NULL;
}
jpeg_stdio_src(解压缩,文件);
jpeg_read_头(&decomp,TRUE);//读取jpeg文件头
jpeg_start_decompress(&decomp);//解压缩文件
行=((decomp.output_width*3+3)和~3);
buffer=(*decomp.mem->alloc_sarray)((j_common_ptr)和decomp,JPOOL_IMAGE,
第1行);
零内存(&bi.bmiHeader,sizeof(BitMapInfo头));
bi.bmiHeader.biSize=sizeof(BitMapInfo标头);
bi.bmiHeader.biWidth=decomp.output\u width;
bi.bmiHeader.biHeight=decomp.output\u height;
bi.bmiHeader.biPlanes=1;
bi.bmiHeader.biBitCount=24;
bi.bmiHeader.biCompression=bi_RGB;
bi.bmiHeader.biSizeImage=行*decomp.output\u高度;
hbm=CreateDIBSection(空值,&bi,DIB_RGB_颜色,(空**)和lpBuf,空值,0);
如果(hbm==NULL)
{
jpeg\u destroy\u解压缩(&decomp);
fclose(文件);
返回NULL;
}
pb=lpBuf+行*反编译输出高度;
while(decomp.output\u扫描线
您使用的是像MFC这样的库吗?如果是这样的话,可能有一种方便的方法可以很容易地做到这一点。否则,您将不得不编写一些代码。是的,我正在使用MFC库。请帮帮我。谢谢。据我所知,并不是所有的库都支持加载JPEG,但至少GDI+正在进行iThanks,但我需要从JPEG缓冲区(而不是从文件)创建HBITMAP。我有一个jpeg缓冲区,我想从这个缓冲区创建HBITMAP。我不想将此缓冲区保存到文件中。非常感谢。您需要创建一个IStream,以便可以使用CImage::Load(IStream)方法并从“缓冲区”加载图像。目前还不清楚该缓冲区是什么样子,CImage::Load只有在具有正确的JPEG文件头时才能工作。CreateStreamOnHGlobal()是一个方便的函数,只要缓冲区实际上是使用GlobalAlloc()创建的。Image::FromStream()。与CImage::Load(IStream)相同的要求谢谢,这正是我想要的。我将C与libjpeg一起使用,GDI+和MFC不在我的考虑范围之内。我甚至认为我需要用GDI绘制每个像素来创建一个!