wp7中的jpeg解码中的内存问题

时间:2013-01-05 17:18:59

标签: c# windows-phone-7 jpeg

我正在使用Windows Phone 7相机应用程序。我需要转换捕获的流,使用exif帮助器修复它的旋转,并保存为jpeg质量,方向,输出大小参数。我跟着exif rotation文章来修复旋转。但核心问题是我需要首先将流解码为jpeg然后执行旋转修复,如图所示,以便将图片保存到媒体库。

我使用以下代码:

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;
        }

在RotateBitMap方法中,我有链接中指定的旋转逻辑,但它创建了一个新的 来自源的WritableBitmap对象如下:

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

问题是

PictureDecoder.decodejpeg - 为我的相机拍摄的流量消耗30 mb 并且在旋转流方法中创建新位图的消耗量增加了30 mb。导致应用程序内存增加60 mb。

由于低端(256mb)windows phone设备的内存导致应用程序崩溃。 为什么解码jpeg需要30mb并且流30mb的旋转。(我试图将旋转流方法中的位图源和目标映射为null并强制gc但是没有用。应用程序在设备上几乎不能获得60mb。我如何能够应对这个要求??

任何想法..?在这些情况下如何优化内存消耗???

注意:我需要从rotatestream方法获取位图,因为我需要使用该位图保存为具有输出大小和质量的jpeg。

1 个答案:

答案 0 :(得分:1)

当您使用JPEG解码时,通常最终会得到一张完整尺寸的照片。 如果用8MP(大约8000000像素)相机拍摄,计算结果如下:

8000000 * 32bits =内存中一张图片的256 000 000位(约为30 MB)

(让我提醒你,HTC Titan II有16MP的摄像头,所以如果你使用全尺寸的照片,内存大约会占用62MB左右!)

显然,要创建一个WriteableBitmap,您需要30MB。为了以某种方式操纵照片,您通常无法在适当的位置进行操作。换句话说,您需要创建一个副本,这就是它重复的原因。 Windows Phone有一种方法可以通过自动降低加载图片的分辨率来防止如此大的内存消耗,但只有当你将它用于以JPEG流作为参数的BitmapImage和SetSource方法时。

我前一段时间在我的文章How to open and work with large photos on Windows Phone中写过它,并在performance considerations for Windows Phone

中提到过

所以,基本上,你应该减少加载的照片的大小(你还需要全尺寸吗?)BitmapImage class可以很容易地为你自动保持在2000x2000 px以下15MB(MAX),所以如果你不想被打扰,你应该没事。

相关问题