Programming Unity3D

DirectX texture to HBitmap

Hi friends!
I was very busy last months, so didn’t update blog. Now i slowly learn Unity3D (such a great tool) for using it in my future projects. Slowly abandoning Flash and Processing. Love how Unity3D handle DirectX11 stuff. All those compute shaders etc.. ) During learning and doing some of my test projects, i was needed convert GPU texture to BITMAP for sending it to printer, so i wrote this small piece of code and want to share it )
I’m not C++ programmer, but this code is working )
If you know how to optimize it, just send me a comment )

Well, there is 2 parts:

1. For DirectX9 conversion

HGDIOBJ extractBitmap(void* texture){

	HBITMAP hBitmapTexture = NULL;
	HGDIOBJ hBitmap;

	IDirect3DTexture9* d3dtex = (IDirect3DTexture9*)texture;
	d3dtex->GetLevelDesc (0, &desc);
	d3dtex->LockRect (0, &lr, NULL, 0);

	hBitmapTexture = CreateCompatibleBitmap(GetDC(NULL), desc.Width, desc.Height);
	hBitmap = CopyImage(hBitmapTexture,IMAGE_BITMAP,desc.Width,desc.Height,LR_CREATEDIBSECTION);
	d3dtex->UnlockRect (0);
	return hBitmap;

2. and for DIrectX11 conversion

HGDIOBJ extractBitmap(void* texture){

	HBITMAP	hBitmapTexture = NULL;
	HGDIOBJ hBitmap;

	ID3D11Texture2D* d3dtex = (ID3D11Texture2D*)texture;
	d3dtex->GetDesc (&desc);

	ID3D11Texture2D* pNewTexture = NULL;
	D3D11_TEXTURE2D_DESC description;
	d3dtex->GetDesc( &description );

	description.BindFlags = 0;

	description.CPUAccessFlags = D3D11_CPU_ACCESS_READ| D3D11_CPU_ACCESS_WRITE;
	description.Usage =	D3D11_USAGE_STAGING;
	HRESULT hr = g_D3D11Device->CreateTexture2D( &description, NULL, &pNewTexture );

	ID3D11DeviceContext* ctx = NULL;
	g_D3D11Device->GetImmediateContext (&ctx);

	ctx->CopyResource( pNewTexture, d3dtex );

	UINT subresource = D3D11CalcSubresource( 0, 0, 0 );
	ctx->Map( pNewTexture, subresource, D3D11_MAP_READ_WRITE, 0, &resource );

	// COPY from texture to bitmap buffer
	uint8_t* sptr = reinterpret_cast<uint8_t*>( resource.pData );
        uint8_t* dptr = new uint8_t[desc.Width*desc.Height*4]; 

        for( size_t h = 0; h < desc.Height; ++h )
            size_t msize = std::min<size_t>( desc.Width* 4, resource.RowPitch );
			memcpy_s( dptr, desc.Width*4, sptr, msize );
           sptr += resource.RowPitch;
           dptr += desc.Width * 4;

		dptr -= desc.Width*desc.Height*4;

		// SWAP BGR to RGB bitmap
		 uint32_t *dPtr = reinterpret_cast<uint32_t*>(dptr);
            for( size_t count = 0; count < desc.Width*desc.Height*4; count += 4 )             {                 uint32_t t = *(dPtr);                 uint32_t t1 = (t & 0x00ff0000) >> 16;
                uint32_t t2 = (t & 0x000000ff) << 16;
                uint32_t t3 = (t & 0x0000ff00);
                uint32_t ta = (t & 0xFF000000);

                *(dPtr++) = t1 | t2 | t3 | ta;

		hBitmapTexture = CreateCompatibleBitmap(GetDC(NULL), desc.Width, desc.Height);   

		hBitmap = CopyImage(hBitmapTexture,IMAGE_BITMAP,desc.Width,desc.Height,LR_CREATEDIBSECTION);	

2 replies on “DirectX texture to HBitmap

Hi i tried the code above for 11 on the latest desktop duplication example how ever all i get is a black screen.

the example reads a frame which is the screen that you see in ID3D11Texture2D DXGI_FORMAT_B8G8R8A8_UNORM .
I am trygin to convert it to rgb.


I was also trying to apply this example in the latest desktop duplication API. It failed at first. However, after a long time debugging, I found that you have to also set the following configure to let it work within the desktop duplication demo program.

description.MiscFlags = 0;

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.