Bitmap::FromFile方法在x86上返回NULL

5

我有一段代码在 Windows 7 64 位上运行:它允许我将包含在 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指出:“在锁定了内存句柄的情况下避免调用对象的方法,否则可能会导致方法调用失败。” - user786653
据我所知,我应该使用Lock/CreateStreamOnHGlobal/Unlock;我会尝试按照你说的去做。 - Maximiliano Santa Cruz
可能是重复的 https://dev59.com/mU3Sa4cB1Zd3GeqPv4U3 - Sergey Vyacheslavovich Brunov
是的,但问题不在于如何创建图像(已解决...某种程度上),而在于它在64位上运行而在32位上却不能工作。 - Maximiliano Santa Cruz
1个回答

12

您提供的代码对我来说很有效。

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

您是否具有GDI+初始化?

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

顺便提一下,关于GDI+未初始化的问题:

GdiplusShutdown(gdiplusToken);

是的,它已经被初始化了。对于win32和win64,代码保持不变。为了给问题增加更多背景,这是使用Firebreath(http://www.firebreath.org)制作的;并且在64位机器上使用MS Visual C++针对32位构建。 - Maximiliano Santa Cruz
请问您能否检查一下最后一个错误(在 Bitmap::FromStream 后调用 GetLastError())? - Sergey Vyacheslavovich Brunov
仅供参考:(http://www.codeproject.com/Messages/787169/Re-Bitmap-FromStream-returns-NULL-solution.aspx)。另外,请问在你的情况下,`GdiplusStartup`函数返回了哪个状态? - Sergey Vyacheslavovich Brunov
1
现在它可以工作了,在我的初始化代码中,我设置了SuppressBackgroundThread = true; 删除那一行就解决了问题! - Maximiliano Santa Cruz
2
太棒了!如果没有这个简单的答案,我可能要搜索几天才能找到可能的错误!因为GDI是在此之后初始化的,所以我一直收到null值,不认为我自己能找到这个小错误 :) - Silencer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接