繁体   English   中英

Windows Phone 8的内存不足异常BitMapImage

[英]Out of Memory exception BitMapImage for Windows Phone 8

单击图片两次或三遍后,appCapImg.SetSource中出现内存不足异常。 我尝试使用一些内存工具进行分析,但是找不到问题。 难道我做错了什么

   byte[] data = null;
 public PhotoCamera cam;
 fnInitializeCamera();

      private void fnInitializeCamera()
    {
        gobject.txtMessage.Text = "Tap the screen to capture a photo.";
        if (PhotoCamera.IsCameraTypeSupported(CameraType.Primary) == true)
        {
            cam = new PhotoCamera(CameraType.Primary);
            cam.CaptureImageAvailable += new    EventHandler<Microsoft.Devices.ContentReadyEventArgs>(cam_CaptureImageAvailable);
            gobject.viewfinderBrush.SetSource(cam);
            if (gobject.Orientation == PageOrientation.PortraitUp)
            {
                gobject.viewfinderTransform.Rotation = 90.0;
            }
        }
        else
        {
            gobject.txtMessage.Text = "A Camera is not available on this device.";
        }
    }

    public void viewfinder_Tapped(object sender, GestureEventArgs e)
    {
        gobject.txtMessage.Text = "Saving Image..";
        if (cam != null)
        {
            try
            {
                cam.CaptureImage();
            }
            catch (Exception ex)
            {
                Deployment.Current.Dispatcher.BeginInvoke(delegate()
                {
                    gobject.txtMessage.Text = ex.Message;
                });
            }
        }
    }

private void RotateStream(Stream stream, int angle)
    {


        stream.Position = 0;
        if (angle % 90 != 0 || angle < 0) throw new ArgumentException();
        if (angle % 360 == 0) data= ((MemoryStream)stream).ToArray(); 

        BitmapImage bitmap = new BitmapImage();
        bitmap.DecodePixelWidth = 480;
        bitmap.SetSource(stream);
        stream.Dispose();
        WriteableBitmap wbSource = new WriteableBitmap(bitmap);
        bitmap.UriSource = null;

        WriteableBitmap wbTarget = null;
        if (angle % 180 == 0)
        {
            wbTarget = new WriteableBitmap(wbSource.PixelWidth, wbSource.PixelHeight);
        }
        else
        {
            wbTarget = new WriteableBitmap(wbSource.PixelHeight, wbSource.PixelWidth);
        }

        int width = wbSource.PixelWidth;
        int height = wbSource.PixelHeight;
        int targetWidth = wbTarget.PixelWidth;
        int[] sourcePixels = wbSource.Pixels;
        int[] targetPixels = wbTarget.Pixels;

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                switch (angle % 360)
                {
                    case 90:
                        targetPixels[(height - y - 1) + x * targetWidth] = sourcePixels[x + y * width];
                        break;
                    case 180:
                        targetPixels[(width - x - 1) + (height - y - 1) * width] = sourcePixels[x + y * width];
                        break;
                    case 270:
                        targetPixels[y + (width - x - 1) * targetWidth] = sourcePixels[x + y * width];
                        break;
                }
            }
        }

        using (MemoryStream targetStream = new MemoryStream())
        {
            wbTarget.SaveJpeg(targetStream, width, height, 0, 100);

            data = targetStream.ToArray();

        }
    }

    void cam_CaptureImageAvailable(object sender, Microsoft.Devices.ContentReadyEventArgs e)
    {
        cam.Dispose();
        Deployment.Current.Dispatcher.BeginInvoke(delegate()
        {
            gobject.disableCameraPlugin();
            gobject.enableWebBrowser();
            BitmapImage appCapImg = new BitmapImage();


            if (gobject.Orientation == PageOrientation.PortraitUp)
            {
                RotateStream(e.ImageStream, 90);
              // Stream stream = new MemoryStream(data1);
               using (MemoryStream streamT = new MemoryStream(data))
               {

                   appCapImg.SetSource(streamT);
               }
               data = null;

            }
            else
            {
                RotateStream(e.ImageStream, 180);
                e.ImageStream.Dispose();
                using (MemoryStream streamT = new MemoryStream(data))
                {

                    appCapImg.SetSource(streamT);
                }
                data = null;

            }

            using (MemoryStream stream = new MemoryStream())
                    {
                        WriteableBitmap wBitmap = new WriteableBitmap(appCapImg);
                        appCapImg.UriSource = null;
                        wBitmap.SaveJpeg(stream, wBitmap.PixelWidth, wBitmap.PixelHeight, 0, 40);
                        stream.Seek(0, SeekOrigin.Begin);
                        data = stream.ToArray();
                    }
                    string base64 = Convert.ToBase64String(data);
                    string[] invokeparam1 = { htmlid, base64 };
                    invokeScript("showimage", invokeparam1);
 }

正如我一直说的,MemoryStream应该小心处理。 使用它之后,您始终可以认为必须在MemoryStream对象上调用dispose。 在以下代码中,您已经很好地处理了此问题,

using (MemoryStream stream = new MemoryStream()) { .... }

您永远不要直接从方法返回任何流。 它没有什么错,除了它违反了您先前应用的原理以在所有Stream对象上手动调用Dispose()。 因此,您可以尝试从方法中返回byte []而不是Stream。

private Stream RotateStream(Stream stream, int angle)

并且始终将所有流对象包括在using {...}块中。 同样,您的代码看起来不完整。 就像变量“ e”代表什么一样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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