【问题标题】:Bitmap::FromFile method returns NULL on x86Bitmap::FromFile 方法在 x86 上返回 NULL
【发布时间】:2012-02-06 16:21:53
【问题描述】:

我有这段代码在 64 位 Windows 7 上运行:它允许我将包含在 std::string (Base64EncodedImage) 中的 Image 的表示转换为 GdiPlus::Bitmap

HRESULT hr; 
using namespace Gdiplus;
std::string decodedImage = Base64EncodedImage;
DWORD imageSize = decodedImage.length();

HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, imageSize);
if (!hMem)
    ErrorExit(TEXT("GlobalAlloc")); //http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx

LPVOID pImage = ::GlobalLock(hMem);
if (!pImage)
    ErrorExit(TEXT("GlobalLock"));

CopyMemory(pImage, decodedImage.c_str(), imageSize);
IStream* pStream = NULL;

BitmapData* bitmapData = new BitmapData;
if (::CreateStreamOnHGlobal(hMem, FALSE, &pStream) != S_OK)
    ErrorExit(TEXT("CreateStreamOnHGlobal"));
else
{
    bitmap = Bitmap::FromStream(pStream);   //FAILS on WIN32
    if (!bitmap)
        ErrorExit(TEXT("FromStream"));

    RECT clientRect;
    GetClientRect(hwnd, &clientRect);

    bitmapClone = bitmap->Clone(0, 0, clientRect.right, clientRect.bottom, PixelFormatDontCare);
    delete bitmap;
    bitmap = NULL;    
}

但它在 Windows 7 32 位上失败,特别是在这一行:

bitmap = Bitmap::FromStream(pStream);

它总是返回NULL,但我不知道这在 x64 上是如何工作的,但在 x86 上却不行。如果有人能启发我,我将不胜感激。

谢谢!

【问题讨论】:

  • 不是专家,但您不应该在将内存传递给CreateStreamonHGlobal 之前GlobalUnlock 吗? MSDN 说“避免在使用 GlobalLock 锁定内存句柄时调用对象的方法。这可能导致方法调用意外失败。”。
  • 据我所知,我应该 Lock/CreateStreamOnHGlobal/Unlock;我会按照你说的去做。
  • 是的,但问题不在于如何创建图像(解决了......有点),而是它如何在 64 位而不是 32 位上工作。

标签: c++ gdi+


【解决方案1】:

你提供的代码很适合我。

但是当我注释了 GDI+ 初始化时,Bitmap::FromStream(pStream) 方法总是返回 NULL 指针。

你有 GDI+ 初始化吗?

GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
// Initialize GDI+.
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

顺便说一下,GDI+ 未初始化:

GdiplusShutdown(gdiplusToken);

【讨论】:

  • 是的,已经初始化了。 win32 和 win64 的代码保持不变。为问题添加更多上下文,这是使用 Firebreath (firebreath.org) 完成的;并在针对 32 位构建的 64 位机器上使用 MS Visual C++。
  • 能否请您检查最后一个错误(在Bitmap::FromStream 之后调用GetLastError())?
  • Just for your information。另外,GdiplusStartup 函数在您的情况下返回哪种状态?
  • 它现在可以工作了,在我的初始化代码中我有 SuppressBackgroundThread = true;删除那条线就成功了!
  • 真棒答案,如果不是这个简单的答案,可能已经搜索了几天可能的错误!此后 GDI 被初始化,所以我总是收到 null,不要认为我自己能找到这个小虫子 :)
猜你喜欢
  • 2012-07-05
  • 2020-01-28
  • 1970-01-01
  • 2016-06-15
  • 1970-01-01
  • 2017-02-23
  • 1970-01-01
  • 2023-04-05
  • 2013-11-19
相关资源
最近更新 更多