【问题标题】:Windows Imaging Component - How to get an encoder from an HBITMAP?Windows 映像组件 - 如何从 HBITMAP 获取编码器?
【发布时间】:2016-07-15 22:45:57
【问题描述】:

我有一个由第 3 方库提供的 HBITMAP,需要将其重新调整为 JPEG 在磁盘上写入。

我从来没有使用过 WIC,所以我一直在关注这个教程:https://msdn.microsoft.com/en-us/library/windows/desktop/ff973956.aspx

我已经从我的 HBITMAP 创建了一个 WicBitmap。

在清单 9 中,很明显我需要一个解码器,但我发现创建它的唯一方法是使用 IWICImagingFactory::CreateDecoderFromFilename。有一个 Initialize 方法接收 IStream,但我不确定使用它的正确方法。

这是将 HBITMAP 保存到磁盘的正确方法吗?如果是这样,我怎样才能从我的 HBITMAP 或 WicBitmap 中获取解码器?

【问题讨论】:

  • 嗯,不,HBITMAP 已经解码。如果你想写一个 JPEG 文件,那么你需要一个 encoder.

标签: c++ windows com atl wic


【解决方案1】:

IWICImagingFactory::CreateBitmapFromHBITMAP 将 GDI 位图作为解码位图导入 WIC,您已经不需要解码器。也就是说,您可以使用编码部分并保存到磁盘。

下面的代码 sn-p 确实完成了它:桌面左上角的 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;
}

【讨论】:

  • 谢谢!我很难发现 IWICFormatConverter 继承自 IWICSourceBitmap,但在那之后,做我需要的事情就变得微不足道了。您的示例完美无缺。
猜你喜欢
  • 1970-01-01
  • 2013-07-01
  • 1970-01-01
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-29
  • 1970-01-01
相关资源
最近更新 更多