3

I have some troubles with saving a image from memorystream.

Here is my code:

MemoryStream ms = new MemoryStream(onimg);

if (ms.Length > 0)
{
    Bitmap bm = new Bitmap(ms);
    returnImage = (Image)bm.Clone();
}
ms.Close();
returnImage.Save(@"C:\img.jpeg");

And on returnImage.Save i have the following exception:

A generic error occurred in GDI+.

If I do not close the MemoryStream all is OK but that requires lot of memory after some time.

How can I do this?

EDIT:That Save is only demonstration.. I really need returnImage for place it in ObservableCollection and display in window when i Need it convert to System.Windows.Media.Imaging.BitmapImage();

[ValueConversion(typeof(System.Drawing.Image), typeof(System.Windows.Media.ImageSource))]
public class ImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
            // empty images are empty...
            if (value == null) { return null; }

            var image = (System.Drawing.Image)value;
            // Winforms Image we want to get the WPF Image from...
            var bitmap = new System.Windows.Media.Imaging.BitmapImage();
            bitmap.BeginInit();
            MemoryStream memoryStream = new MemoryStream();
            // Save to a memory stream...
            image.Save(memoryStream, ImageFormat.Bmp);
            // Rewind the stream...
            memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
            bitmap.StreamSource = memoryStream;
            bitmap.EndInit();
            return bitmap;
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        return null;
    }
}

And XAML when i do this

<DataTemplate>
   <Image Width="32" Height="32" Source="{ Binding Thumb, Converter={StaticResource    imageConverter} }" />
</DataTemplate>
Krizz
  • 11,362
  • 1
  • 30
  • 43
Aldos
  • 193
  • 2
  • 12
  • 1
    What happens if you .Save before you .Close the MemoryStream? – Brissles Jan 15 '12 at 19:51
  • 1
    Why do you have to use a Bitmap object? Cant you save the file using FileStream? What is onimg? – craig1231 Jan 15 '12 at 19:51
  • can't you report the actual exception message ? – Felice Pollano Jan 15 '12 at 19:52
  • 1
    I've run into this problem before, the error message is simply: 'A generic error occurred in GDI+'. Check here for some more info: http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/b15357f1-ad9d-4c80-9ec1-92c786cca4e6/ – Brissles Jan 15 '12 at 19:53
  • Brissles:returnImage is global variable and I need it in another class after this method ends. So i haven't any chance to close Memorystream after I working with returnImage. – Aldos Jan 15 '12 at 19:59

2 Answers2

4

According to documentation:

You must keep the stream open for the lifetime of the Bitmap.

Bitmap needs to store its data samewhere, and I deduce (although have no proof for this) that Bitmap does not copy the data, instead using the stream, keeping a lock on it.

Also, there is no evidence that Clone will create new bitmap with the copy of byte representation. And your testcase suggests it is not a case.

Therefore, I am afraid you need to keep your stream open for the lifetime of your image. It requires memory, true, but otherwise if Bitmap copied the data, you will still need that memory for the bitmap representation. Therefore, no more memory is consumed with open stream (if my previous deduction was true).

If you really want to overcome the bitmap's dependency on the original memory stream, you will need to draw the orginal bitmap on the new one instead of cloning like here. But this will impact the performance, I would better re-analyze if it is not a good idea to keep the original stream, just making sure it is closed when bitmap is disposed.

Community
  • 1
  • 1
Krizz
  • 11,362
  • 1
  • 30
  • 43
2

Isn't a save to disk basically a clone?

using (MemoryStream ms = new MemoryStream(onimg))
{
    if (ms.Length > 0)
    {
        using (Bitmap bm = new Bitmap(ms))
        {
            bm.Save(@"C:\img.jpeg");
        }
    }
}
Joe
  • 80,724
  • 18
  • 127
  • 145