wp7中的内存不足异常

时间:2012-01-18 06:32:41

标签: c# windows-phone-7 out-of-memory image-capture isolatedstorage

我想创建一个使用相机捕获图像并将其存储在手机的隔离存储中的应用程序。但是,我能够在每次运行中存储7个图像(即每次激活模拟器时)和我捕获和保存的八个图像,我得到一个内存不足的例外。如果我必须在隔离存储中存储更多图像,我必须停止调试并重新启动调试。我是wp7开发的新手。我正在使用模拟器用于调试。请帮助

    Stream doc_photo;
    List<document> doc_list = new List<document>();
    document newDoc = new document();
    public Page2()
    {
        InitializeComponent();
    }


    private void captureDocumentImage(object sender, RoutedEventArgs e)
    {
        ShowCameraCaptureTask();
    }

    private void ShowCameraCaptureTask()
    {
        CameraCaptureTask photoCameraCapture = new CameraCaptureTask();
        photoCameraCapture = new CameraCaptureTask();
        photoCameraCapture.Completed += new EventHandler<PhotoResult>photoCameraCapture_Completed);
        photoCameraCapture.Show();
    }

    void photoCameraCapture_Completed(object sender, PhotoResult e)
    {
        if (e.TaskResult == TaskResult.OK)
        {
            capturedImage.Source = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
            doc_photo = e.ChosenPhoto;

        }
    }

    private void SaveToIsolatedStorage(Stream imageStream, string fileName)
    {
        using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
        {
            if (myIsolatedStorage.FileExists(fileName))
            {
                myIsolatedStorage.DeleteFile(fileName);
            }

            IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(fileName);
            BitmapImage bitmap = new BitmapImage();
            bitmap.SetSource(imageStream);
            try
            {
                WriteableBitmap wb = new WriteableBitmap(bitmap);
                wb.SaveJpeg(fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
                fileStream.Close();
            }
            catch (OutOfMemoryException e1)
            {
                MessageBox.Show("memory exceeded");
            }

        }
    }

    private void save_buttonclicked(object sender, RoutedEventArgs e)
    {

        if (namebox.Text != "" && doc_photo!=null)
        {

            newDoc.doc_name = namebox.Text;

            IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();
            if(!myIsolatedStorage.DirectoryExists(App.current_panorama_page))
            {
               myIsolatedStorage.CreateDirectory(App.current_panorama_page);
            }
            newDoc.photo = App.current_panorama_page + "/" + namebox.Text + ".jpg";//
            SaveToIsolatedStorage(doc_photo, newDoc.photo);

            doc_list.Add(newDoc);
            NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));

        }
        else
        {
            if (namebox.Text == "")
            {
                MessageBox.Show("Enter the name");
            }
            else if (doc_photo == null) 
            {
                MessageBox.Show("Capture an Image");
            }

        }
    }

1 个答案:

答案 0 :(得分:3)

您将位图保存为'doc_list',而不仅仅是URL,因此手机会将您捕获的每张图像保存在内存中。您应该寻求一种解决方案,使用常规图像控件和“isostore://”URL在UI中引用图像。

编辑:

在下面的示例中,我使用ObservableCollection来存储IsoImageWrappers。后一类通过使用构造函数中给出的URI实例化隔离文件流来处理与隔离存储的连接。

ObservableCollection将在添加新图像时通知WP7框架。存储图像几乎与您的原始提案一样。

列表框绑定是:

 <ListBox Grid.Row="0" Height="495" Margin="0" Name="listBox1" Width="460" >
    <ListBox.ItemTemplate>
       <DataTemplate>
          <Image Source="{Binding Source}" Width="Auto" />
       </DataTemplate>
    </ListBox.ItemTemplate>
 </ListBox>

以及带有帮助类等丑陋内联的代码:

using System;
using System.Collections.ObjectModel;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Tasks;

namespace WP7Photo
{
    public partial class MainPage : PhoneApplicationPage
    {
        public class IsoImageWrapper
        {
            public string Uri { get; set; }

            public ImageSource Source
            {
                get
                {
                    IsolatedStorageFile isostore = IsolatedStorageFile.GetUserStoreForApplication();
                    var bmi = new BitmapImage();
                    bmi.SetSource(isostore.OpenFile(Uri, FileMode.Open, FileAccess.Read));
                    return bmi;
                }
            }
        }

        public ObservableCollection<IsoImageWrapper> Images { get; set; }

        // Constructor
        public MainPage()
        {
            InitializeComponent();
            Images = new ObservableCollection<IsoImageWrapper>();
            listBox1.ItemsSource = Images;
        }

        private void Button1Click(object sender, RoutedEventArgs e)
        {
            var cameraTask = new CameraCaptureTask();
            cameraTask.Completed += new EventHandler<PhotoResult>(cameraTask_Completed);
            cameraTask.Show();
        }

        void cameraTask_Completed(object sender, PhotoResult e)
        {
            if (e.TaskResult != TaskResult.OK)
            {
                return;
            }

            StorePhoto(e);
        }

        private void StorePhoto(PhotoResult photo)
        {
            IsolatedStorageFile isostore = IsolatedStorageFile.GetUserStoreForApplication();
            if (!isostore.DirectoryExists("photos"))
            {
                isostore.CreateDirectory("photos");
            }

            var filename = "photos/"  + System.IO.Path.GetFileName(photo.OriginalFileName);

            if (isostore.FileExists(filename)) { isostore.DeleteFile(filename);}

            using (var isoStream = isostore.CreateFile(filename))
            {
                photo.ChosenPhoto.CopyTo(isoStream);
            }
            Images.Add(new IsoImageWrapper {Uri = filename});
        }
    }
}