繁体   English   中英

VS + Win32 + C ++ + PNG

[英]VS + Win32 + C++ + PNG

我在资源编辑器中添加了png作为资源,但是如何加载和显示呢? 我想在图片控件或所有者绘图中显示它。 我不想让外部文件随处可见。 我想我记得在某处读过一些文章,您可以将文件“绑定”到可执行文件,但基本上仍将它们当作外部文件来引用吗?

(创建一个具有一些背景和一些按钮状态的简单gui界面,但只需要一个exe,而不是exe + button1.png + button2.png等。我也需要透明功能,因此不需要BMP。我也将希望将其全部保留在Windows中(没有libpng等)

这是我用来加载PNG资源以使用Direct2D渲染的代码(但它并不限制您仅使用PNG格式或仅使用D2D):

/**
 * Loads image from the specified resource and creates Direct2D bitmap object for that image.
 *
 * Parameters:
 * >pszResourceName
 * Image resource name.
 * >pszResourceType
 * Image resource type.
 * >pImagingFactory
 * Pointer to an instance of IWICImagingFactory object.
 * >ppBitmapSource
 * Receives loaded bitmap.
 *
 * Returns:
 * Standard HRESULT code.
 */
HRESULT directx_toolkit::loadBitmapFromResource(
    _In_z_ LPCTSTR pszResourceName,
    _In_z_ LPCTSTR pszResourceType,
    _In_ IWICImagingFactory* pImagingFactory,
    _COM_Outptr_result_maybenull_ IWICFormatConverter** ppBitmapSource) const
{
    ATLADD com_ptr<IWICFormatConverter> converter {};
    HRESULT hr = E_FAIL;
    HRSRC hResource = FindResource(ATL::_AtlBaseModule.GetResourceInstance(), pszResourceName, pszResourceType);
    if (nullptr != hResource)
    {
        HGLOBAL hData = LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), hResource);
        if (nullptr != hData)
        {
            void* pData = LockResource(hData);
            DWORD nSize = SizeofResource(ATL::_AtlBaseModule.GetResourceInstance(), hResource);
            if (pData && nSize)
            {
                // Create a WIC stream to map onto the memory.
                ATLADD com_ptr<IWICStream> stream {};
                hr = pImagingFactory->CreateStream(stream.getAddressOf());
                if (SUCCEEDED(hr))
                {
                    hr = stream->InitializeFromMemory(reinterpret_cast<BYTE*> (pData), nSize);
                    if (SUCCEEDED(hr))
                    {
                        // Prepare decoder for the stream, the first image frame and conveter (to change image color
                        // format).
                        ATLADD com_ptr<IWICBitmapDecoder> decoder {};
                        hr = pImagingFactory->CreateDecoderFromStream(
                            stream.get(), nullptr, WICDecodeMetadataCacheOnLoad, decoder.getAddressOf());
                        if (SUCCEEDED(hr))
                        {
                            ATLADD com_ptr<IWICBitmapFrameDecode> frame {};
                            hr = decoder->GetFrame(0, frame.getAddressOf());
                            if (SUCCEEDED(hr))
                            {
                                hr = pImagingFactory->CreateFormatConverter(converter.getAddressOf());
                                if (SUCCEEDED(hr))
                                {
                                    hr = converter->Initialize(
                                        frame.get(),
                                        GUID_WICPixelFormat32bppPBGRA,
                                        WICBitmapDitherTypeNone,
                                        nullptr,
                                        0,
                                        WICBitmapPaletteTypeMedianCut);
                                }
                            }
                        }
                    }
                }
            }
        }
        else
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
        }
    }
    else
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
    }
    *ppBitmapSource = SUCCEEDED(hr) ? converter.detach() : nullptr;
    return hr;
}


/**
 * Loads image from the specified resource and creates Direct2D bitmap object for that image.
 *
 * Parameters:
 * >pszResourceName
 * Image resource name.
 * >pszResourceType
 * Image resource type.
 * >pImagingFactory
 * Pointer to an instance of IWICImagingFactory object.
 * >pDC
 * Direct2D context.
 * >ppBitmap
 * Receives loaded bitmap.
 *
 * Returns:
 * Standard HRESULT code.
 *
 * Remarks:
 * Since 'ID2D1DeviceContext::CreateBitmapFromWicBitmap' can't be called simultaneously from multiple threads, caller
 * should synchronize access to the 'pDC'.
 */
HRESULT directx_toolkit::loadBitmapFromResource(
    _In_z_ LPCTSTR pszResourceName,
    _In_z_ LPCTSTR pszResourceType,
    _In_ IWICImagingFactory* pImagingFactory,
    _In_ ID2D1DeviceContext* pDC,
    _COM_Outptr_result_maybenull_ ID2D1Bitmap1** ppBitmap) const
{
    ATLADD com_ptr<ID2D1Bitmap1> bitmap {};
    ATLADD com_ptr<IWICFormatConverter> converter {};
    HRESULT hr = loadBitmapFromResource(pszResourceName, pszResourceType, pImagingFactory, converter.getAddressOf());
    if (SUCCEEDED(hr))
    {
        hr = pDC->CreateBitmapFromWicBitmap(converter.get(), bitmap.getAddressOf());
    }
    *ppBitmap = SUCCEEDED(hr) ? bitmap.detach() : nullptr;
    return hr;
}

ATLADD com_ptr是我的ATL::CComPtr类似物)

毫无疑问-您可以使用32bpp BMP来获取带有透明蒙版的资源。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM