如何在 C++ 中从 png 图像的字节数组创建位图

发布于 2025-01-13 11:15:16 字数 1326 浏览 2 评论 0 原文

尝试使用下面的代码,但它似乎不起作用。 bm 的值为空

BYTE imageData[] =
    {
    0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00,
    0x10, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x03, 0x00, 0x00, 0x00, 0x1f, 0x5d, 0x52, 0x1c, 0x00, 0x00, 0x00, 0x0f, 0x50,
    0x4c, 0x54, 0x45, 0x7a, 0xdf, 0xfd, 0xfd, 0xff, 0xfc, 0x39, 0x4d, 0x52, 0x19, 0x16, 0x15, 0xc3, 0x8d, 0x76, 0xc7,
    0x36, 0x2c, 0xf5, 0x00, 0x00, 0x00, 0x40, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x95, 0xc9, 0xd1, 0x0d, 0xc0, 0x20,
    0x0c, 0x03, 0xd1, 0x23, 0x5d, 0xa0, 0x49, 0x17, 0x20, 0x4c, 0xc0, 0x10, 0xec, 0x3f, 0x53, 0x8d, 0xc2, 0x02, 0x9c,
    0xfc, 0xf1, 0x24, 0xe3, 0x31, 0x54, 0x3a, 0xd1, 0x51, 0x96, 0x74, 0x1c, 0xcd, 0x18, 0xed, 0x9b, 0x9a, 0x11, 0x85,
    0x24, 0xea, 0xda, 0xe0, 0x99, 0x14, 0xd6, 0x3a, 0x68, 0x6f, 0x41, 0xdd, 0xe2, 0x07, 0xdb, 0xb5, 0x05, 0xca, 0xdb,
    0xb2, 0x9a, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
    };
    HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, sizeof(imageData)); 
    LPVOID pImage = ::GlobalLock(hMem);
    memcpy(pImage, imageData, sizeof(imageData)); 

    IStream* pStream = NULL;
    ::CreateStreamOnHGlobal(hMem, FALSE, &pStream);
    Gdiplus::Bitmap* bm = Gdiplus::Bitmap::FromStream(pStream, true);

Tried using the below code but it does not seem to work. The value of bm is null

BYTE imageData[] =
    {
    0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00,
    0x10, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x03, 0x00, 0x00, 0x00, 0x1f, 0x5d, 0x52, 0x1c, 0x00, 0x00, 0x00, 0x0f, 0x50,
    0x4c, 0x54, 0x45, 0x7a, 0xdf, 0xfd, 0xfd, 0xff, 0xfc, 0x39, 0x4d, 0x52, 0x19, 0x16, 0x15, 0xc3, 0x8d, 0x76, 0xc7,
    0x36, 0x2c, 0xf5, 0x00, 0x00, 0x00, 0x40, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x95, 0xc9, 0xd1, 0x0d, 0xc0, 0x20,
    0x0c, 0x03, 0xd1, 0x23, 0x5d, 0xa0, 0x49, 0x17, 0x20, 0x4c, 0xc0, 0x10, 0xec, 0x3f, 0x53, 0x8d, 0xc2, 0x02, 0x9c,
    0xfc, 0xf1, 0x24, 0xe3, 0x31, 0x54, 0x3a, 0xd1, 0x51, 0x96, 0x74, 0x1c, 0xcd, 0x18, 0xed, 0x9b, 0x9a, 0x11, 0x85,
    0x24, 0xea, 0xda, 0xe0, 0x99, 0x14, 0xd6, 0x3a, 0x68, 0x6f, 0x41, 0xdd, 0xe2, 0x07, 0xdb, 0xb5, 0x05, 0xca, 0xdb,
    0xb2, 0x9a, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
    };
    HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, sizeof(imageData)); 
    LPVOID pImage = ::GlobalLock(hMem);
    memcpy(pImage, imageData, sizeof(imageData)); 

    IStream* pStream = NULL;
    ::CreateStreamOnHGlobal(hMem, FALSE, &pStream);
    Gdiplus::Bitmap* bm = Gdiplus::Bitmap::FromStream(pStream, true);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

衣神在巴黎 2025-01-20 11:15:16

我可以建议两种将 PNG 转换为 BMP 的方法。

  1. 您可以使用第三方库。对于 opencv 来说,它会是这样的:

     Mat image = imread("image.png", -1);
     垫图像_bmp;
     image.convertTo(image_bmp, CV_8UC3);
     imwrite("image.bmp", image_bmp);
    
  2. 在VS中你可以使用GDI+。以下代码在我的VS2019中可以运行。


#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
#pragma comment (lib,"Gdiplus.lib")
using namespace Gdiplus;
INT GetEncoderClsid(const WCHAR* format, CLSID* pClsid);  // helper function
INT main()
{
    // Initialize GDI+.
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    CLSID   encoderClsid;
    Status  stat;
    Image* image = new Image(L"image.png");
    // Get the CLSID of the encoder.
    GetEncoderClsid(L"image/bmp", &encoderClsid);

    stat = image->Save(L"image.bmp", &encoderClsid, NULL);

    if (stat == Ok)
    printf("Image was saved successfully\n");
    else
    printf("Failure: stat = %d\n", stat);
    delete image;
    GdiplusShutdown(gdiplusToken);
    return 0;
}
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
    UINT  num = 0;          // number of image encoders
    UINT  size = 0;         // size of the image encoder array in bytes
    ImageCodecInfo* pImageCodecInfo = NULL;
    GetImageEncodersSize(&num, &size);
    if (size == 0)
        return -1;  // Failure
    pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
    if (pImageCodecInfo == NULL)
        return -1;  // Failure
    GetImageEncoders(num, size, pImageCodecInfo);
    for (UINT j = 0; j < num; ++j)
    {
        if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
        {
            *pClsid = pImageCodecInfo[j].Clsid;
            free(pImageCodecInfo);
            return j;  // Success
        }
    }
    free(pImageCodecInfo);
    return -1;  // Failure
}

I can suggest 2 ways to convert PNG to BMP.

  1. You can use third-party libraries. In case of opencv it will be something like that:

     Mat image = imread("image.png", -1);
     Mat image_bmp;
     image.convertTo(image_bmp, CV_8UC3);
     imwrite("image.bmp", image_bmp);
    
    1. In VS you can use GDI+. The following code is runnable in my VS2019.

#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
#pragma comment (lib,"Gdiplus.lib")
using namespace Gdiplus;
INT GetEncoderClsid(const WCHAR* format, CLSID* pClsid);  // helper function
INT main()
{
    // Initialize GDI+.
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    CLSID   encoderClsid;
    Status  stat;
    Image* image = new Image(L"image.png");
    // Get the CLSID of the encoder.
    GetEncoderClsid(L"image/bmp", &encoderClsid);

    stat = image->Save(L"image.bmp", &encoderClsid, NULL);

    if (stat == Ok)
    printf("Image was saved successfully\n");
    else
    printf("Failure: stat = %d\n", stat);
    delete image;
    GdiplusShutdown(gdiplusToken);
    return 0;
}
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
    UINT  num = 0;          // number of image encoders
    UINT  size = 0;         // size of the image encoder array in bytes
    ImageCodecInfo* pImageCodecInfo = NULL;
    GetImageEncodersSize(&num, &size);
    if (size == 0)
        return -1;  // Failure
    pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
    if (pImageCodecInfo == NULL)
        return -1;  // Failure
    GetImageEncoders(num, size, pImageCodecInfo);
    for (UINT j = 0; j < num; ++j)
    {
        if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
        {
            *pClsid = pImageCodecInfo[j].Clsid;
            free(pImageCodecInfo);
            return j;  // Success
        }
    }
    free(pImageCodecInfo);
    return -1;  // Failure
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文