Ales
Ales

Reputation: 193

How to Copy Bitmap.Image in c#

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>

Upvotes: 3

Views: 9655

Answers (2)

Krizz
Krizz

Reputation: 11542

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.

Upvotes: 4

Joe
Joe

Reputation: 82594

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

Upvotes: 2

Related Questions