简体   繁体   中英

Out of memory exception in wp7

I want to make an application which captures images using the camera and stores it in the isolated storage of the phone.How ever, i am able to store 7 images in each run(ie each time the emulator is activated) and for the eight image that i capture and save, i get an out of memory exception.If I have to store more images in the isolated storage, i have to stop debugging and restart debugging.I am new to wp7 development.I am using the emulator for debugging.Please help

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

        }
    }

you are saving the bitmap to 'doc_list', not just the URL, so the phone will have each image you capture in memory. You should probably go for a solution where the images are referenced in the UI using regular image controls and the 'isostore://' URLs.

EDIT:

In the example below I use an ObservableCollection for storing IsoImageWrappers . The latter class handles the connection to isolated storage, by instantiating an isolated file stream with the URI given in constructor.

The ObservableCollection will notify the WP7 framework when new images are added. Storing images is almost as your original proposal.

The list box binding is:

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

and the code with ugly inline of helper classes etc:

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

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