VS + Win32 + C ++ + PNG

时间:2016-01-31 22:46:04

标签: c++ visual-studio winapi png

我在资源编辑器中添加了一个png作为资源但是如何加载和显示?我想在图片控件或所有者绘图中显示它。我不希望有一个外部文件浮动。我想我记得在哪里读过你可以“绑定”文件到可执行文件但是基本上仍然把它们称为外部文件?

(用一些背景和一些按钮状态创建一个简单的gui界面......但只需要一个exe,而不是exe + button1.png + button2.png等。我也需要透明度功能,所以没有BMP。我也想把它全部保存在windows中(没有libpng等等))

1 个答案:

答案 0 :(得分:0)

这是我用来加载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 来获取具有透明度掩码的资源。