locked
Problem converting large BMP files to JPEG using BitmapDecoder class RRS feed

  • Question

  • I am getting a OutOfMemoryException when attempting to load a very large BMP file using BitmapDecoder and GetPixelDataAsync().   The BMP file is roughly 500MB, and represents a full page 1200 dpi color image scanned from a flatbed scanner.   My goal is to convert this large BMP file into JPEG using BitmapDecoder/BitmapEncoder.   I have no problems at 600 dpi, but once I go above that, I get OutOfMemoryException.

    Code snippet:

                using (var str = await input.OpenAsync(FileAccessMode.Read))
                {
                    try
                    {
                        BitmapDecoder dec = await BitmapDecoder.CreateAsync(str);
                        dpi = dec.DpiX;
                        width = dec.PixelWidth;
                        height = dec.PixelHeight;
                        BitmapTransform dummyTransform = new BitmapTransform();
                        PixelDataProvider pixelDataProvider = await dec.GetPixelDataAsync(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Ignore, dummyTransform,
                            ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb);
                        pixelData = pixelDataProvider.DetachPixelData();
                    }
                    catch (Exception e)
                    {
                        HPLoggingLib.Logging.WriteException(e);
                        return false;
                    }
                }

    The DPI is 1200, and the PixelWidth and PixelHeight are both 10200.    The exception is thrown when I call dec.GetPixelDataAsync().  

    Is there any way with BitmapDecoder/Encoder to convert large files, or do i need to use another mechanism?

    Thanks!

    Thursday, November 14, 2013 6:47 PM

All replies

  • Are you building as 64bit or 32bit (or AnyCPU, which will default to 32bit)? Uncompressed you have about a 3GB image which won't fit well into 32bit address space.

    --Rob

    Thursday, November 14, 2013 7:29 PM
    Moderator
  • Hi Rob,

    I tested on x64 explicitly, and that worked better.   We were building "Any CPU" and that did default to 32 bit.  

    However, the amount of memory used is not 3gb as you indicated, it's pretty much the size of the BMP file, which was ~500mb.    I noticed that memory use jumped up accordingly on x64 by 500mb when I called GetPixelDataAsync.    I also noticed another 500mb jump when I did the corresponding SetPixelData() call on the BitmapEncoder to create the JPG file.    All of which was freed later when a GC occurred.

    So it would seem that this should work just fine for 32bit, as I am no where near the 3GB memory constraint.  Any thoughts on that?

    Thanks

    Jeremy

    Friday, November 15, 2013 7:38 PM