3

I am getting an Invalid cross-thread access when I try to use a BitMapImage in my cam_CaptureImageAvailable method, I tried using a Dispatcher but that gave me a Cannot access a closed Stream error, System.ObjectDisposedException was unhandled.

// Informs when full resolution picture has been taken, saves to local media library and isolated storage.
    void cam_CaptureImageAvailable(object sender, Microsoft.Devices.ContentReadyEventArgs e)
    {

        string fileName = folderName+"\\MyImage" + savedCounter + ".jpg";

        try
        {   // Write message to the UI thread.
            Deployment.Current.Dispatcher.BeginInvoke(delegate()
            {
                txtDebug.Text = "Captured image available, saving picture ," + fileName;
            });

            // Save picture to the library camera roll.
            //library.SavePictureToCameraRoll(fileName, e.ImageStream);


            // Write message to the UI thread.
            Deployment.Current.Dispatcher.BeginInvoke(delegate()
            {
                //txtDebug.Text = "Picture has been saved.";

            });

            // Set the position of the stream back to start
            e.ImageStream.Seek(0, SeekOrigin.Begin);


            // Save picture as JPEG to isolated storage.
            using (IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (IsolatedStorageFileStream targetStream = isStore.OpenFile(fileName, FileMode.Create, FileAccess.Write))
                {

                    // Initialize the buffer for 4KB disk pages.
                    byte[] readBuffer = new byte[4096];
                    int bytesRead = -1;

                    // Copy the image to isolated storage. 
                    while ((bytesRead = e.ImageStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
                    {
                        targetStream.Write(readBuffer, 0, bytesRead);

                    }

                }

                var bitmapImage = new BitmapImage(); 
                bitmapImage.SetSource(e.ImageStream); 
                WriteableBitmap wb = new WriteableBitmap(bitmapImage);
                IsolatedStorageFile myStore = IsolatedStorageFile.GetUserStoreForApplication(); 
                using (IsolatedStorageFileStream myFileStream = myStore.CreateFile(fileName)) 
                { 
                    wb.SaveJpeg(myFileStream, 10, 10, 0, 70); 
                }

            }





        }
        finally
        {
            // Close image stream
            e.ImageStream.Close();
        }

    }

Tried this as well

Deployment.Current.Dispatcher.BeginInvoke(delegate()
                {
                    var bitmapImage = new BitmapImage();
                    bitmapImage.SetSource(e.ImageStream);
                    WriteableBitmap wb = new WriteableBitmap(bitmapImage);
                    IsolatedStorageFile myStore = IsolatedStorageFile.GetUserStoreForApplication();
                    using (IsolatedStorageFileStream myFileStream = myStore.CreateFile(fileName))
                    {
                        wb.SaveJpeg(myFileStream, 10, 10, 0, 70);//compressing image
                    }
                });

Can anyone help me I would really appreciate it thanks.

M_K
  • 3,247
  • 6
  • 30
  • 47

1 Answers1

2

You have to create the BitmapImage and the WriteableBitmap on the UI thread because they are DependencyObjects.

The reason you get the ObjectDisposedException error is that the stream for the image is closed already when the dispatcher handles your request.

Did you try moving that code into your Dispatcher invocation?

 e.ImageStream.Close();

The code for the dispatcher does not get executed immediately but at a later point in time, but you have closed the stream already.

If that doesnt work, then you could workaround your problem by reading the stream to memory in CaptureImageAvailable and then pass that MemoryStream as source to your BitmapImage.

thumbmunkeys
  • 20,606
  • 8
  • 62
  • 110
  • Hi pivotnig, I am using memory stream and it works but I am only getting the first Image every time I take a picture, here is the code I am using code `e.ImageStream.Seek(0, SeekOrigin.Begin);e.ImageStream.CopyTo(ms);` and in the dispatcher I have `var bitmapImage = new BitmapImage();bitmapImage.SetSource(ms);WriteableBitmap wb = new WriteableBitmap(bitmapImage);` Thanks for your help – M_K Apr 16 '12 at 00:23
  • I am only getting the first Image every time I take a picture – M_K Apr 16 '12 at 00:36
  • It's Ok I had the Memory stream as a global variable:) – M_K Apr 16 '12 at 00:39