VS + Win32 + C++ + PNG

VS + Win32 + C++ + PNG

本文关键字:PNG C++ Win32 VS      更新时间:2023-10-16

我已经在资源编辑器中添加了一个 png 作为资源,但如何加载和显示?我想在图片控件或所有者绘制中显示它。我不想让外部文件漂浮。我想我记得在某处读到您可以将文件"绑定"到可执行文件,但基本上仍然将它们称为外部文件?

(创建一个简单的类似GUI的界面,有一些背景和一些按钮状态......但只需要一个 exe,而不是 exe + 按钮 1.png + 按钮 2.png 等。我也需要透明度功能,所以没有BMP。我也想把它全部保留在窗口中(没有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 来获取带有透明度蒙版的资源。