【问题标题】:Loading an image from memory, GDI+从内存中加载图像,GDI+
【发布时间】:2010-12-11 17:06:56
【问题描述】:

这是一个快速简单的问题:使用 C++ 中的 GDI+,我将如何从内存中的像素数据加载图像?

【问题讨论】:

标签: c++ image graphics gdi+ load


【解决方案1】:

使用SHCreateMemStream,它需要一个指向数据的指针和数据的大小。

IStream *pStream = SHCreateMemStream((BYTE *) InputBuffer, Size);
// Do what you want
pStream->Release();

【讨论】:

    【解决方案2】:

    有一个位图构造函数,它直接接受一个 BITMAPINFO 和一个指向像素数据的指针,例如:

    BITMAPINFO bmi;
    memset(&bmi, 0, sizeof(bmi));
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = 32;
    bmi.bmiHeader.biHeight = 32;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biBitCount = 24;
    char data[32 * 32 * 3];
    // Write pixels to 'data' however you want...
    Gdiplus::Bitmap* myImage = new Gdiplus::Bitmap(&bmi, data);
    

    对于 RGB 图像没关系,如果它是调色板图像,您需要为 RGBQUADS 等分配足够空间的 BITMAPINFO。

    【讨论】:

      【解决方案3】:

      可能没有您希望的那么简单,但您可以使用像素数据在内存中制作 BMP 文件:

      如有必要,请将您的像素数据转换为 BITMAP 友好格式。如果您已经拥有 24 位 RGB 像素数据,则可能不需要转换。

      创建(在内存中)一个 BITMAPFILEHEADER 结构,后跟一个 BITMAPINFO 结构。

      现在你已经得到了你需要的东西,你需要把它放到一个 IStream 中,这样 GDI+ 才能理解它。可能最简单(虽然不是最高效)的方法是:

      1. 使用 BITMAPFILEHEADER 的大小、BITMAPINFO 和您的像素数据调用 GlobalAlloc()。
      2. 按顺序,将 BITMAPFILEHEADER、BITMAPINFO 和像素数据复制到新内存中(调用 GlobalLock 以获取新内存指针)。
      3. 调用 CreateStreamOnHGlobal() 为您的内存 BMP 获取 IStream。

      现在,调用 GDI+ Image::FromStream() 方法将图像加载到 GDI+。

      祝你好运!

      【讨论】:

      • 呃,你是对的;这比我想象的要复杂得多。我希望我可以让它工作。
      • 祝你好运! BITMAPINFO 的东西很挑剔。在十六进制编辑器中查看 24 位 BMP 文件可能会有所帮助,以便将您正在做的事情与真实的事情进行比较。 (Visual Studio 可以做到这一点;打开文件,但使用“打开方式”选项,然后选择“二进制编辑器”)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-01
      • 2015-09-20
      • 2010-10-21
      • 2012-06-01
      • 2018-12-25
      • 1970-01-01
      相关资源
      最近更新 更多