c# - 如何在 C# 中复制 Bitmap.Image

标签 c# image memorystream bitmapimage

我在从内存流中保存图像时遇到了一些麻烦。

这是我的代码:

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

returnImage.Save 上我有以下异常:

A generic error occurred in GDI+.

如果我不关闭 MemoryStream 一切正常,但一段时间后需要大量内存。

我该怎么做?

编辑:保存只是演示。我真的需要 returnImage 将它放在 ObservableCollection 中,并在我需要将它转换为 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;
    }
}

当我执行此操作时使用 XAML

<DataTemplate>
   <Image Width="32" Height="32" Source="{ Binding Thumb, Converter={StaticResource    imageConverter} }" />
</DataTemplate>

最佳答案

根据 documentation :

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

Bitmap 需要将其数据存储在同一位置,我推断(尽管没有证据证明这一点)Bitmap 不会复制数据,而是使用流并对其保持锁定。

p>

此外,没有证据表明Clone 会使用字节表示的副本创建新的位图。你的测试用例表明它不是一个案例。

因此,恐怕您需要在图像的整个生命周期内保持流打开状态。它需要内存,没错,但如果 Bitmap 复制了数据,您仍然需要该内存来表示位图。因此,打开流不再消耗内存(如果我之前的推论是正确的)。

如果你真的想克服位图对原始内存流的依赖,你需要在新位图上绘制原始位图,而不是像 here 那样克隆。 但这会影响性能,我最好重新分析是否保留原始流不是一个好主意,只是确保在处理 bitmap 时关闭它。

关于c# - 如何在 C# 中复制 Bitmap.Image,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8872767/

相关文章:

c# - 编译错误,.NET 没有看到存在的函数

c# - MemoryStream 写入数据的地方

image - Unity-3d-5 缩放图像 16 :9 to other resolutions

Android内存泄漏,没有静态变量

C# MemoryStream & GZipInputStream : Can't . 读取超过 256 个字节

c# - UWP BitmapImage 到流

c# - EditorFor() 和 html 属性

c# - ubuntu中的Firefox浏览器检测

c# - 在 UpdatePanel 中回发后添加用户控件,然后是另一个回发 - 如何在用户控件中获取控件的输入?

image - 如何在opencv中找到图像中形状的角点?