我正在尝试编写一个函数来读取使用Windows Imaging Component复制到剪贴板的图像。目前,我的代码基于如何加载资源,但已修改为使用剪贴板。初始化流的一切工作正常但是一旦我尝试使用CreateDecoderFromeStream
它就失败了。我试过从很多地方复制图像都无济于事。 WIC无法读取的复制图像格式有什么不同吗?
以下是我的代码......
创建要从剪贴板中读取的内存对象
COMStreamSPtr WIC::createStreamFromClipboard() {
IStream* ipStream = NULL;
COMStreamSPtr stream = nullptr;
CoInitialize(nullptr);
if (!IsClipboardFormatAvailable(CF_BITMAP) && !IsClipboardFormatAvailable(CF_DIB) && !IsClipboardFormatAvailable(CF_DIBV5))
goto Return;
if (!OpenClipboard(NULL))
goto Return;
// Load the clipboard
HGLOBAL hMem = GetClipboardData(CF_BITMAP);
if (hMem == NULL || hMem == INVALID_HANDLE_VALUE)
hMem = GetClipboardData(CF_DIB);
if (hMem == NULL || hMem == INVALID_HANDLE_VALUE)
hMem = GetClipboardData(CF_DIBV5);
if (hMem == NULL || hMem == INVALID_HANDLE_VALUE)
goto CloseClipboard;
// Lock the clipboard, getting a pointer to its data
LPVOID pvSourceClipboardData = GlobalLock(hMem);
if (pvSourceClipboardData == NULL)
goto CloseClipboard;
// Read the clipboard data size
DWORD dwClipboardSize = GlobalSize(hMem);
if (dwClipboardSize == 0)
goto GlobalUnlock;
// Allocate memory to hold the clipboard data
HGLOBAL hgblClipboardData = GlobalAlloc(GMEM_MOVEABLE, dwClipboardSize);
if (hgblClipboardData == NULL)
goto GlobalUnlock;
// Get a pointer to the allocated memory
LPVOID pvClipboardData = GlobalLock(hgblClipboardData);
if (pvClipboardData == NULL)
goto FreeData;
// Copy the data from the clipboard to the new memory block
CopyMemory(pvClipboardData, pvSourceClipboardData, dwClipboardSize);
GlobalUnlock(hgblClipboardData);
// Create a stream on the HGLOBAL containing the data
if (SUCCEEDED(CreateStreamOnHGlobal(hgblClipboardData, TRUE, &ipStream))) {
stream = std::make_shared<COMStream>(ipStream);
goto CloseClipboard;
}
FreeData:
// Couldn't create stream; free the memory
GlobalFree(hgblClipboardData);
GlobalUnlock:
// Unlock the clipboard data
GlobalUnlock(hMem);
CloseClipboard:
// Close the clipboard
CloseClipboard();
Return:
// No need to unlock or free the resource
CoUninitialize(); // CoInialize is called by my COMObjects in the constructor so this is just decrementing the count.
return stream;
}
使用返回的流在代码中的其他地方。
WICBitmapDecoderSPtr WIC::createDecoderFromStream(COMStreamSPtr stream) {
if (isCOMObjectNull(stream))
return nullptr;
IWICImagingFactory* ipFactory = NULL;
IWICBitmapDecoder* ipDecoder = NULL;
WICBitmapDecoderSPtr decoder = nullptr;
// Create the factory
if (FAILED(CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ipFactory))))
goto Return;
// Create the decoder
if (FAILED(ipFactory->CreateDecoderFromStream(stream->ipObject, NULL, WICDecodeMetadataCacheOnDemand, &ipDecoder)))
goto ReleaseFactory; // FAILS HERE
decoder = std::make_shared<WICBitmapDecoder>(ipDecoder);
ReleaseFactory:
ipFactory->Release();
Return:
return decoder;
}
答案 0 :(得分:0)
我终于想出了如何做到这一点。我所做的是使用了IWICImagingFactory
CreateBitmapFromHBITMAP
函数。由于从剪贴板中读取HBITMAP
非常简单,因此解决方案变得非常简单。
IWICBitmapSource* WIC::readSourceFromClipboard() {
IWICBitmapSource* ipSource = NULL;
if (Clipboard::containsFormat(CF_BITMAP)) {
if (OpenClipboard(NULL)) {
HBITMAP hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);
ipSource = createSourceFromHBitmap(hBitmap);
CloseClipboard();
}
}
return ipSource;
}
IWICBitmapSource* WIC::createSourceFromHBitmap(HBITMAP hBitmap) {
if (hBitmap == NULL)
return NULL;
IWICImagingFactory* ipFactory = NULL;
IWICBitmap* ipBitmap = NULL;
CoInitialize(NULL);
// Create the factory
if (FAILED(CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ipFactory))))
goto Return;
// Create the bitmap
if (FAILED(ipFactory->CreateBitmapFromHBITMAP(hBitmap, NULL, WICBitmapIgnoreAlpha, &ipBitmap)))
goto ReleaseFactory;
ReleaseFactory:
ipFactory->Release();
Return:
CoUninitialize();
return ipBitmap;
}