0

我在 windows phone 7 相机应用程序上工作。我需要转换捕获的流,使用 exif 帮助程序修复它的旋转,并保存为 jpeg,并带有质量、方向、输出大小参数。我按照 exif 旋转文章修复旋转。但核心问题是我需要先将流解码为 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。

4

1 回答 1

1

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

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

(让我提醒你,HTC Titan II 有一个 16MP 的相机,所以如果你使用全尺寸的照片,它会占用大约 62MB 的内存!!)

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

我前段时间在我的文章How to open and work with large photos on Windows Phone中写过它,它在 Windows Phone 的性能注意事项中有所提及

所以,基本上,你应该减小加载照片的大小(你需要全尺寸吗?)并且BitmapImage 类可以很容易地自动将它保持在 2000x2000 像素以下,大约是 15MB(最大),所以如果您不想为此烦恼,那应该没问题。

于 2013-01-06T01:21:30.947 回答