how to set image of Picture Control?

mc 5,426 Reputation points
2024-08-28T12:16:04.8466667+00:00

User's image

I use direct2d create ID2D1Bitmap how to set this bitmap as Picture Controls's Source?

Windows development | Windows API - Win32
0 comments No comments
{count} votes

Accepted answer
  1. Castorix31 90,686 Reputation points
    2024-08-28T14:37:44.46+00:00

    It is not common to use a ID2D1Bitmap in a control, which are mainly used to be drawn

    Otherwise, you can convert it to HBITMAP

    A way with WIC and GDI+ (quick test, to be improved as I don't do this...) :

    (tested on Windows 10 22H2)

    HRESULT ConvertD2DBitmapToHBITMAP(ID2D1Bitmap* pD2DBitmap, ID2D1DeviceContext* pD2D1DeviceContext, HBITMAP* phBitmap)
    {
    	*phBitmap = nullptr;
    	IWICImagingFactory2* pWICImagingFactory2;
    	HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory2, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pWICImagingFactory2));
    	if (SUCCEEDED(hr))
    	{
    		IWICBitmapEncoder* pEncoder;
    		hr = pWICImagingFactory2->CreateEncoder(GUID_ContainerFormatJpeg, nullptr, &pEncoder);
    		if (SUCCEEDED(hr))
    		{
    			IStream* pStream;
    			hr = CreateStreamOnHGlobal(nullptr, TRUE, &pStream);
    			hr = pEncoder->Initialize(pStream, WICBitmapEncoderNoCache);
    			if (SUCCEEDED(hr))
    			{
    				IWICBitmapFrameEncode* pFrameEncoder;
    				hr = pEncoder->CreateNewFrame(&pFrameEncoder, nullptr);
    				if (SUCCEEDED(hr))
    				{
    					hr = pFrameEncoder->Initialize(nullptr);
    					ID2D1Device* pD2D1Device;
    					pD2D1DeviceContext->GetDevice(&pD2D1Device);
    					IWICImageEncoder* pImageEncoder;
    					hr = pWICImagingFactory2->CreateImageEncoder(pD2D1Device, &pImageEncoder);
    					if (SUCCEEDED(hr))
    					{
    						hr = pImageEncoder->WriteFrame(pD2DBitmap, pFrameEncoder, nullptr);
    						hr = pFrameEncoder->Commit();
    						hr = pEncoder->Commit();
    
    						STATSTG stat;
    						hr = pStream->Stat(&stat, STATFLAG_NONAME);
    						if (SUCCEEDED(hr))
    						{
    							ULARGE_INTEGER liSize = stat.cbSize;
    							auto pBytes = new BYTE[liSize.QuadPart];
    							ULONG nBytesRead;
    							LARGE_INTEGER liZero = {};
    							hr = pStream->Seek(liZero, STREAM_SEEK_SET, nullptr);
    							hr = pStream->Read(pBytes, liSize.LowPart, &nBytesRead);
    
    							HBITMAP hBitmap = NULL;
    							Gdiplus::Bitmap* pBitmap = new Gdiplus::Bitmap(pStream);
    							if (pBitmap->GetLastStatus() == Gdiplus::Ok)
    							{
    								pBitmap->GetHBITMAP(Gdiplus::Color(255, 255, 255), &hBitmap);
    								*phBitmap = hBitmap;
    								delete pBitmap;
    							}
    						}
    						pImageEncoder->Release();
    					}
    					pD2D1Device->Release();
    					pFrameEncoder->Release();
    				}
    			}
    			pStream->Release();
    			pEncoder->Release();
    		}
    		pWICImagingFactory2->Release();
    	}
    	return hr;
    }
    
    

    At beginning :

    
    #include "gdiplus.h"  
    using namespace Gdiplus;
    #pragma comment(lib, "gdiplus.lib")  
    
    

    then to intialize GDI+ :

    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    
    

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.