0
以下是我的代码(感谢其他人)阅读图像文件并返回Gdiplus :: Bitmap。我的问题是,在创建位图(它似乎工作)和调用代码时,我完成位图的代码(在底部)是正确的,我可以只调用delete pBitmap;Gdiplus ::位图释放内存
在此先感谢
HRESULT ImageUtilities::LoadImageFromFile(
std::string path,
UINT destinationWidth,
UINT destinationHeight,
UINT frame,
Gdiplus::Bitmap **ppBitmap,
double *resX,
double *resY)
{
CComPtr<IWICBitmapFrameDecode> pSource;
CComPtr<IWICBitmapDecoder> pDecoder;
CComPtr<IWICFormatConverter> pConverter;
CComPtr<IWICBitmapScaler> pScaler;
// get image factory
IWICImagingFactory *pImageFactory = WICImagingFactory::GetInstance().GetFactory();
// get/determine image decoder
HRESULT hr = pImageFactory->CreateDecoderFromFilename(MultiByteToUnicode(path).c_str(), NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &pDecoder);
// get the specified frame from the image
if (SUCCEEDED(hr))
{
// Validate the given frame index nFrame
UINT nCount = 0;
// Get the number of frames in this image
if (SUCCEEDED(pDecoder->GetFrameCount(&nCount)))
{
if (frame >= nCount)
frame = nCount - 1; // If the requested frame number is too big, default to the last frame
}
// get the frame
if (SUCCEEDED(hr))
{
hr = pDecoder->GetFrame(0, &pSource);
}
}
// get the image converter
if (SUCCEEDED(hr))
{
// Convert the image format to 32bppPBGRA (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED)
hr = pImageFactory->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
pSource->GetResolution(resX, resY);
// if a new width or height was specified, create an IWICBitmapScaler and use it to resize the image
if (destinationWidth != 0 || destinationHeight != 0)
{
UINT originalWidth, originalHeight;
hr = pSource->GetSize(&originalWidth, &originalHeight);
if (SUCCEEDED(hr))
{
if (destinationWidth == 0)
{
FLOAT scalar = static_cast<FLOAT>(destinationHeight)/static_cast<FLOAT>(originalHeight);
destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
}
else if (destinationHeight == 0)
{
FLOAT scalar = static_cast<FLOAT>(destinationWidth)/static_cast<FLOAT>(originalWidth);
destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
}
hr = pImageFactory->CreateBitmapScaler(&pScaler);
if (SUCCEEDED(hr))
{
hr = pScaler->Initialize(pSource, destinationWidth, destinationHeight, WICBitmapInterpolationModeCubic);
}
if (SUCCEEDED(hr))
{
hr = pConverter->Initialize(pScaler, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
}
}
else // Don't scale the image.
{
hr = pConverter->Initialize(pSource, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
}
// finally create a GDI+ Bitmap from the WIC bitmap.
if (SUCCEEDED(hr))
{
// calculate stride and necessary buffer size
UINT uWidth, uHeight;
hr = pConverter->GetSize(&uWidth, &uHeight);
const UINT cbStride = 4 * uWidth;
const UINT cbBufferSize = cbStride * uHeight;
// allocate buffer then copy pixels
// NOTE: we are responable to delete this buffer when we delete the Bitmap
BYTE *pBitmapBuffer = new BYTE[cbBufferSize];
WICRect rc;
rc.X = 0; rc.Y = 0; rc.Width = uWidth; rc.Height = uHeight;
hr = pConverter->CopyPixels(&rc, cbStride, cbBufferSize, (BYTE *)pBitmapBuffer);
// create a Gdiplus::Bitmap object
Gdiplus::Bitmap *pBitmap = new Gdiplus::Bitmap(uWidth, uHeight, cbStride,
PixelFormat32bppPARGB, pBitmapBuffer);
delete[] pBitmapBuffer;
if (Gdiplus::Ok != pBitmap->GetLastStatus())
{
return E_FAIL;
}
*ppBitmap = pBitmap;
}
return hr;
}
我改变了上面下面,事情似乎运行更好
Gdiplus::Bitmap *pBitmap = new Gdiplus::Bitmap(uWidth, uHeight, PixelFormat32bppPARGB);
Gdiplus::BitmapData bd;
Gdiplus::Rect rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
Gdiplus::Status status = pBitmap->LockBits(&rect, Gdiplus::ImageLockModeWrite, PixelFormat32bppPARGB, &bd);
if (Gdiplus::Ok == status)
{
memcpy(bd.Scan0, pBitmapBuffer, cbStride*uHeight);
status = pBitmap->UnlockBits(&bd);
}
delete[] pBitmapBuffer;