简体   繁体   中英

memory issue in jpeg decoding in wp7

I working on windows phone 7 camera app.I need to convert captured stream ,fix it rotation using exif helper and save as jpeg with quality,orientation,output size parameters.I followed exif rotation article to fix rotation. But the core problem is I need to decode the stream to jpeg first and then perform rotation fix as mentioned in order to save picture to media library.

I use following code:

private WriteableBitmap DecodeImage(Stream photo, int angle)
 {
            WriteableBitmap source = PictureDecoder.DecodeJpeg(photo);

            photo.Seek(0, SeekOrigin.Begin);           

            System.GC.Collect();

            UiDispatcher.BeginInvoke(() =>
            {
                MessageBox.Show(App.LogMemory("after decode"));
            });
            switch (angle)
            {
                case 90:
                case 270:
                    return RotateBitmap(source, source.PixelHeight,
                        source.PixelWidth, angle);
                case 180:
                    return RotateBitmap(source, source.PixelWidth,
                        source.PixelHeight, angle);
                default:
                    return source;
            }
            return null;
        }

In RotateBitMap method i have the rotation logic as specified in link but it creates a new WritableBitmap object from source as follows:

WritablBitmap target = new WritableBitmap(soure.width,source.height); //source is the bitmap passed in argument.

The problem is

PictureDecoder.decodejpeg --consumes 30 mb for my camera captured stream and creation of the new bitmap in rotate stream method is consuming 30 mb more.Resulting in hike of 60 mb application memory.

this is causing application crash due to memory in lower end(256mb) windows phone devices. Why is decoding jpeg take 30mb and rotation of stream 30mb.(I tried to source and target bitmaps in rotate stream method to null and forced gc but were of no use.Applications hardly get 60mb on devices.How can i cope up with this requirement??

Any ideas..?How to optimize memory consumption in these cases???

Note: I need to take bitmap from rotatestream method as result as I need to use that bitmap to save as jpeg with output size,quality.

When you use JPEG decoding, you usually end up with a photo in it's full size. In case it was taken with 8MP (roughly 8000000 pixels) camera, the calculation is this:

8000000 * 32bits = 256 000 000 bits for one picture in memory (which is roughly around 30MB)

(let me remind you that the HTC Titan II has a camera of 16MP, so if you used a photo in full size, it would take up roughly around 62MB in memory!!)

Obviously, to create just one WriteableBitmap, you need 30MB. In order to manipulate the photo in some way, you usually can't do it in place. In other words, you need to create a copy, and that's why it duplicates. Windows Phone has a way of preventing such a big memory consumption by automatically lowering the resolution of the loaded picture, but only when you use it with BitmapImage and SetSource method which takes JPEG stream as a parameter.

I wrote about it some time ago in my article How to open and work with large photos on Windows Phone and it's mentioned in the performance considerations for Windows Phone

So, basically, you should cut down the size of the loaded photo (do you need it in full size anyway?) and the BitmapImage class can easily do it for you automatically keeping it under 2000x2000 px which is roughly 15MB (MAX), so you should be fine if you don't want to be bothered with that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM