locked
How to draw some text on a Bitmap in memory and then How to get the bitmap pixels in bytes?

    Question

  • Hi,

    I am new to win8 metro. I am working with c++/cx.

    Follow is What I want to do use win8 APIs :

    1) I want create a bitmap in memory.

    2) I want to draw some text on this bitmap.

    3) I want to save the pixels of the result bitmap into a byte array.

    So what should I do?

    Some links ,Some words Will be very helpfull to me ,Thx.

    Wednesday, March 28, 2012 1:01 PM

Answers

  • ComPtr<IStream> stream;
    	auto refStream = ref new InMemoryRandomAccessStream();
    	DX::ThrowIfFailed(
    		CreateStreamOverRandomAccessStream(reinterpret_cast<IUnknown*>(refStream) ,IID_PPV_ARGS(&stream))
    		);
    	GUID wicFormat = GUID_ContainerFormatBmp;
    	SaveBitmapToStream(m_logoBitmap, m_wicFactory, m_d2dContext, wicFormat, stream.Get());
    
    	refStream->Seek(0);
    	ComPtr<IStream> stream2;
    	long streamSize = refStream->Size;
    	DX::ThrowIfFailed(
    		CreateStreamOverRandomAccessStream(reinterpret_cast<IUnknown*>(refStream) ,IID_PPV_ARGS(&stream2))
    		);
    	ComPtr<IWICBitmapDecoder> wicBitmapDecoder;
    	DX::ThrowIfFailed(
    		m_wicFactory->CreateDecoderFromStream(stream2.Get(),nullptr,WICDecodeMetadataCacheOnDemand,&wicBitmapDecoder)
    		);
    
    		 ComPtr<IWICBitmapFrameDecode> wicBitmapFrame;
        DX::ThrowIfFailed(
            wicBitmapDecoder->GetFrame(0, &wicBitmapFrame)
            );
    
        ComPtr<IWICFormatConverter> wicFormatConverter;
        DX::ThrowIfFailed(
            m_wicFactory->CreateFormatConverter(&wicFormatConverter)
            );
    
        DX::ThrowIfFailed(
            wicFormatConverter->Initialize(
                wicBitmapFrame.Get(),
                GUID_WICPixelFormat32bppPBGRA,
                WICBitmapDitherTypeNone,
                nullptr,
                0.0,
                WICBitmapPaletteTypeCustom  // the BGRA format has no palette so this value is ignored
                )
            );
    
    	double dpiX = 96.0f;
    	double dpiY = 96.0f;
    	DX::ThrowIfFailed(
    		wicFormatConverter->GetResolution(&dpiX, &dpiY)
    		);
    
    	UINT uiWidth = (UINT)width;
    	UINT uiHeight = (UINT)height;
    
    	UINT cbStride = uiWidth * sizeof(float);
    	UINT cbBufferSize = cbStride * uiHeight;
    	float *pixels = new float[cbBufferSize / sizeof(float)];
    
    	if (pixels)
    	{    
    		WICRect rc;
    		rc.X = 0;
    		rc.Y = 0;
    		rc.Width = uiWidth;
    		rc.Height = uiHeight;
    
    		DX::ThrowIfFailed(
    			wicFormatConverter->CopyPixels(&rc, cbStride, cbBufferSize, reinterpret_cast<BYTE*>(pixels))
    			);
    	}

    I sovled it by up codes

    The code code :

    		DX::ThrowIfFailed(
    			wicFormatConverter->CopyPixels(&rc, cbStride, cbBufferSize, reinterpret_cast<BYTE*>(pixels))
    			);

    • Marked as answer by lihex Thursday, April 5, 2012 7:02 AM
    Thursday, April 5, 2012 7:02 AM

All replies

  • You can draw text with the DirectWrite API. See the DirectWrite Hello World sample for an example.

    The Xaml API don't provide any high level functions for rendering into a bitmap. You can create a WriteableBitmap and use DirectX and Xaml interop to use the image created with DirectWrite as a Xaml SurfaceImageSource. There is a previous discussion of this at DirectWrite in XAML-DirectX interop.

    --Rob

    • Proposed as answer by Jesse Jiang Thursday, March 29, 2012 10:55 AM
    Wednesday, March 28, 2012 3:26 PM
    Owner
  • ComPtr<IStream> stream;
    	auto refStream = ref new InMemoryRandomAccessStream();
    	DX::ThrowIfFailed(
    		CreateStreamOverRandomAccessStream(reinterpret_cast<IUnknown*>(refStream) ,IID_PPV_ARGS(&stream))
    		);
    	GUID wicFormat = GUID_ContainerFormatBmp;
    	SaveBitmapToStream(m_logoBitmap, m_wicFactory, m_d2dContext, wicFormat, stream.Get());
    
    	refStream->Seek(0);
    	ComPtr<IStream> stream2;
    	long streamSize = refStream->Size;
    	DX::ThrowIfFailed(
    		CreateStreamOverRandomAccessStream(reinterpret_cast<IUnknown*>(refStream) ,IID_PPV_ARGS(&stream2))
    		);
    	ComPtr<IWICBitmapDecoder> wicBitmapDecoder;
    	DX::ThrowIfFailed(
    		m_wicFactory->CreateDecoderFromStream(stream2.Get(),nullptr,WICDecodeMetadataCacheOnDemand,&wicBitmapDecoder)
    		);
    
    		 ComPtr<IWICBitmapFrameDecode> wicBitmapFrame;
        DX::ThrowIfFailed(
            wicBitmapDecoder->GetFrame(0, &wicBitmapFrame)
            );
    
        ComPtr<IWICFormatConverter> wicFormatConverter;
        DX::ThrowIfFailed(
            m_wicFactory->CreateFormatConverter(&wicFormatConverter)
            );
    
        DX::ThrowIfFailed(
            wicFormatConverter->Initialize(
                wicBitmapFrame.Get(),
                GUID_WICPixelFormat32bppPBGRA,
                WICBitmapDitherTypeNone,
                nullptr,
                0.0,
                WICBitmapPaletteTypeCustom  // the BGRA format has no palette so this value is ignored
                )
            );
    
    	double dpiX = 96.0f;
    	double dpiY = 96.0f;
    	DX::ThrowIfFailed(
    		wicFormatConverter->GetResolution(&dpiX, &dpiY)
    		);
    
    	UINT uiWidth = (UINT)width;
    	UINT uiHeight = (UINT)height;
    
    	UINT cbStride = uiWidth * sizeof(float);
    	UINT cbBufferSize = cbStride * uiHeight;
    	float *pixels = new float[cbBufferSize / sizeof(float)];
    
    	if (pixels)
    	{    
    		WICRect rc;
    		rc.X = 0;
    		rc.Y = 0;
    		rc.Width = uiWidth;
    		rc.Height = uiHeight;
    
    		DX::ThrowIfFailed(
    			wicFormatConverter->CopyPixels(&rc, cbStride, cbBufferSize, reinterpret_cast<BYTE*>(pixels))
    			);
    	}

    I sovled it by up codes

    The code code :

    		DX::ThrowIfFailed(
    			wicFormatConverter->CopyPixels(&rc, cbStride, cbBufferSize, reinterpret_cast<BYTE*>(pixels))
    			);

    • Marked as answer by lihex Thursday, April 5, 2012 7:02 AM
    Thursday, April 5, 2012 7:02 AM