Windows 成像组件 - 如何从 HBITMAP 获取编码器?
Windows Imaging Component - How to get an encoder from an HBITMAP?
我有一个由第 3 方库提供的 HBITMAP,需要将其重新缩放为 JPEG 格式写入磁盘。
我从来没有用过 WIC,所以我一直在学习这个教程:https://msdn.microsoft.com/en-us/library/windows/desktop/ff973956.aspx
我已经从我的 HBITMAP 创建了一个 WicBitmap。
在清单 9 中,很明显我需要一个解码器,但我发现创建它的唯一方法是使用 IWICImagingFactory::CreateDecoderFromFilename。有一个接收 IStream 的 Initialize 方法,但我不确定使用它的正确方法。
这是将 HBITMAP 保存到磁盘的正确方法吗?如果是这样,我怎样才能从我的 HBITMAP 或 WicBitmap 获得解码器?
IWICImagingFactory::CreateBitmapFromHBITMAP
将 GDI 位图作为解码位图导入 WIC,您已经不需要解码器了。也就是说,您可以使用编码部分并保存到磁盘。
下面的代码片段确实完成了它:从桌面左上角的 800x600 位图作为 HBITMAP
,然后保存到 JPEG 文件中。
#include "stdafx.h"
#include <wincodecsdk.h>
#include <atlbase.h>
#define __C ATLENSURE_SUCCEEDED
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
{
HBITMAP hBitmap;
{
HDC hDc = GetDC(NULL);
hBitmap = CreateCompatibleBitmap(hDc, 800, 600);
HDC hBitmapDc = CreateCompatibleDC(hDc);
HGDIOBJ hPreviousBitmap = SelectObject(hBitmapDc, hBitmap);
BitBlt(hBitmapDc, 0, 0, 800, 600, hDc, 0, 0, SRCCOPY);
SelectObject(hBitmapDc, hPreviousBitmap);
DeleteDC(hBitmapDc);
ReleaseDC(NULL, hDc);
}
CComPtr<IWICImagingFactory> pFactory;
__C(pFactory.CoCreateInstance(CLSID_WICImagingFactory));
CComPtr<IWICBitmap> pBitmap;
__C(pFactory->CreateBitmapFromHBITMAP(hBitmap, NULL, WICBitmapIgnoreAlpha, &pBitmap));
CComPtr<IWICBitmapEncoder> pBitmapEncoder;
__C(pFactory->CreateEncoder(GUID_ContainerFormatJpeg, NULL, &pBitmapEncoder));
CComPtr<IWICStream> pFileStream;
__C(pFactory->CreateStream(&pFileStream));
__C(pFileStream->InitializeFromFilename(L"D:\Output.jpg", GENERIC_WRITE));
__C(pBitmapEncoder->Initialize(pFileStream, WICBitmapEncoderNoCache));
CComPtr<IWICBitmapFrameEncode> pBitmapFrameEncode;
CComPtr<IPropertyBag2> pPropertyBag;
__C(pBitmapEncoder->CreateNewFrame(&pBitmapFrameEncode, &pPropertyBag));
PROPBAG2 Property;
ZeroMemory(&Property, sizeof Property);
Property.pstrName = L"ImageQuality";
CComVariant vQuality(0.85f);
__C(pPropertyBag->Write(1, &Property, &vQuality));
__C(pBitmapFrameEncode->Initialize(pPropertyBag));
__C(pBitmapFrameEncode->WriteSource(pBitmap, NULL));
__C(pBitmapFrameEncode->Commit());
__C(pBitmapEncoder->Commit());
}
CoUninitialize();
return 0;
}
我有一个由第 3 方库提供的 HBITMAP,需要将其重新缩放为 JPEG 格式写入磁盘。
我从来没有用过 WIC,所以我一直在学习这个教程:https://msdn.microsoft.com/en-us/library/windows/desktop/ff973956.aspx
我已经从我的 HBITMAP 创建了一个 WicBitmap。
在清单 9 中,很明显我需要一个解码器,但我发现创建它的唯一方法是使用 IWICImagingFactory::CreateDecoderFromFilename。有一个接收 IStream 的 Initialize 方法,但我不确定使用它的正确方法。
这是将 HBITMAP 保存到磁盘的正确方法吗?如果是这样,我怎样才能从我的 HBITMAP 或 WicBitmap 获得解码器?
IWICImagingFactory::CreateBitmapFromHBITMAP
将 GDI 位图作为解码位图导入 WIC,您已经不需要解码器了。也就是说,您可以使用编码部分并保存到磁盘。
下面的代码片段确实完成了它:从桌面左上角的 800x600 位图作为 HBITMAP
,然后保存到 JPEG 文件中。
#include "stdafx.h"
#include <wincodecsdk.h>
#include <atlbase.h>
#define __C ATLENSURE_SUCCEEDED
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
{
HBITMAP hBitmap;
{
HDC hDc = GetDC(NULL);
hBitmap = CreateCompatibleBitmap(hDc, 800, 600);
HDC hBitmapDc = CreateCompatibleDC(hDc);
HGDIOBJ hPreviousBitmap = SelectObject(hBitmapDc, hBitmap);
BitBlt(hBitmapDc, 0, 0, 800, 600, hDc, 0, 0, SRCCOPY);
SelectObject(hBitmapDc, hPreviousBitmap);
DeleteDC(hBitmapDc);
ReleaseDC(NULL, hDc);
}
CComPtr<IWICImagingFactory> pFactory;
__C(pFactory.CoCreateInstance(CLSID_WICImagingFactory));
CComPtr<IWICBitmap> pBitmap;
__C(pFactory->CreateBitmapFromHBITMAP(hBitmap, NULL, WICBitmapIgnoreAlpha, &pBitmap));
CComPtr<IWICBitmapEncoder> pBitmapEncoder;
__C(pFactory->CreateEncoder(GUID_ContainerFormatJpeg, NULL, &pBitmapEncoder));
CComPtr<IWICStream> pFileStream;
__C(pFactory->CreateStream(&pFileStream));
__C(pFileStream->InitializeFromFilename(L"D:\Output.jpg", GENERIC_WRITE));
__C(pBitmapEncoder->Initialize(pFileStream, WICBitmapEncoderNoCache));
CComPtr<IWICBitmapFrameEncode> pBitmapFrameEncode;
CComPtr<IPropertyBag2> pPropertyBag;
__C(pBitmapEncoder->CreateNewFrame(&pBitmapFrameEncode, &pPropertyBag));
PROPBAG2 Property;
ZeroMemory(&Property, sizeof Property);
Property.pstrName = L"ImageQuality";
CComVariant vQuality(0.85f);
__C(pPropertyBag->Write(1, &Property, &vQuality));
__C(pBitmapFrameEncode->Initialize(pPropertyBag));
__C(pBitmapFrameEncode->WriteSource(pBitmap, NULL));
__C(pBitmapFrameEncode->Commit());
__C(pBitmapEncoder->Commit());
}
CoUninitialize();
return 0;
}