我在从内存流中保存图像时遇到了一些麻烦。
这是我的代码:
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
上我有以下例外:
GDI +中发生了一般性错误。
如果我不关闭MemoryStream
一切都没问题,但一段时间后需要大量内存。
我该怎么做?
编辑:Save只是演示..我真的需要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>
答案 0 :(得分:4)
您必须在Bitmap的生命周期内保持流打开。
位图需要将其数据存储在同一个地方,我推断(虽然没有证据证明这一点)Bitmap
不会复制数据,而是使用流来保持锁定。
此外,没有证据表明Clone
将使用字节表示的副本创建新的位图。而你的测试用例表明它不是一个案例。
因此,我担心您需要在图片的生命周期内保持您的信息流畅通。它需要内存,true,但是如果Bitmap复制了数据,你仍然需要那个内存用于位图表示。因此,开放流不会消耗更多内存(如果我以前的推论是真的)。
如果你真的想要克服位图对原始内存流的依赖性,你需要绘制新的原始位图而不是克隆,如{{ 3}}。 但是这会影响性能,我最好重新分析是否保留原始流不是一个好主意,只是确保在位图处理时它已关闭。
答案 1 :(得分:2)
基本上不是保存到磁盘克隆吗?
using (MemoryStream ms = new MemoryStream(onimg))
{
if (ms.Length > 0)
{
using (Bitmap bm = new Bitmap(ms))
{
bm.Save(@"C:\img.jpeg");
}
}
}