locked
Size limit of pictures drawn with DirectX (OutOfMemoryException when creating bitmap)

    Question

  • In our application images are drawn with DirectX. It works on desktops, but when testing the app on ARM tablets, the ID2D1DeviceContext::CreateBitmapFromWicBitmap function returns OutOfMemory error when we pass in large images. The error occured with apporximately 2500 x 1500 pixel images, and when we scaled down the image to 1920 x something, it worked properly.

    Is there an explicit size limit for images processed with DirectX? Does it depend on the architecture (x86 or ARM) or the video card in the device?

    Or maybe we use the Direct2D API incorrectly? The following code processes and draws the image:

    // Get the WIC Imaging factory and the device context.
    ComPtr<IWICImagingFactory2> wicFactory = GetWICImagingFactory();
    ComPtr<ID2D1DeviceContext> d2dDeviceContext = GetD2DDeviceContext();

    ComPtr<IWICBitmapDecoder> decoder; ComPtr<IWICBitmapFrameDecode> frame; ComPtr<IWICFormatConverter> wicBitmap;

    ComPtr<ID2D1Bitmap> d2d1Bitmap; ComPtr<IWICStream> wicStream; wicFactory->CreateStream(&wicStream); // file is the pointer to the image bytes in memory and length is the size of the image file in bytes. wicStream->InitializeFromMemory((BYTE*)file, length); DX::ThrowIfFailed( wicFactory->CreateDecoderFromStream(wicStream.Get(), nullptr, WICDecodeMetadataCacheOnDemand, &decoder) ); DX::ThrowIfFailed( decoder->GetFrame(0, &frame) ); DX::ThrowIfFailed( wicFactory->CreateFormatConverter(&wicBitmap) ); // I'm not sure I use the correct parameters, they are taken from a code sample. DX::ThrowIfFailed( wicBitmap->Initialize( frame.Get(), GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0, WICBitmapPaletteTypeCustom)); // This is the call which returns the OutOfMemory error for large images. auto hr = d2dDeviceContext->CreateBitmapFromWicBitmap( wicBitmap.Get(), D2D1::BitmapProperties( D2D1::PixelFormat(), DisplayProperties::LogicalDpi, DisplayProperties::LogicalDpi), &d2d1Bitmap);




    • Edited by MarkVincze Thursday, September 20, 2012 10:22 AM
    Thursday, September 20, 2012 10:21 AM

Answers

All replies

  • My guess is you're hitting a device limit of 2048 pixels for the texture. See the Feature Level limits:

    http://msdn.microsoft.com/en-us/library/ff476876(v=vs.85).aspx#Overview

    • Proposed as answer by Jesse Jiang Friday, September 21, 2012 3:13 AM
    • Marked as answer by MarkVincze Friday, September 21, 2012 7:00 AM
    Thursday, September 20, 2012 6:51 PM
  • Thanks! I wasn't aware of this page.
    Friday, September 21, 2012 7:00 AM
  • Hi, do you have method to resolve this problem?can you give some code? thank you!

    Wednesday, October 24, 2012 3:08 AM
  • Hi, do you have method to resolve this problem?can you give some code? thank you!

    Two options:

    1. Resample your image to a smaller size

    2. Break it up into tiles that are within the target device's limits

    Wednesday, October 24, 2012 3:30 AM
  • Hi!

    I don't have any sophisticated solutions to this problem, I simply made sure that I don't try to draw any images larger then 2048 pixels in any dimension (all of the images we draw are created by us, so it was easy to achieve this condition).

    If you have to draw images which are not known beforehand and they might be too large, you could try to resize them before drawing. For example, you can use the BitmapEncoder class to resize an image.

    Wednesday, October 24, 2012 7:38 AM