在运行时更新 PNG 图像会引发 GDI+ 溢出异常
Posted
技术标签:
【中文标题】在运行时更新 PNG 图像会引发 GDI+ 溢出异常【英文标题】:Update PNG Image at runtime throws GDI+ overflow exception 【发布时间】:2019-01-03 20:18:58 【问题描述】:我制作了一个列表框,其中包含绑定了图像的项目(Binding BitmapSource、UpdateSourceTrigger=PropertyChanged)。他们在运行时更新,一切都很好,但他们的背景是黑色的,而不是我希望的透明。
现在我想拥有与 PNG 相同的功能。 所以现在我确实绑定到 PNG 的 URI 并尝试更改图像并随后通知,但我收到错误(可能是因为我想在图像已经打开时保存图像?)
我会尽力展示所有相关代码: XAML:
<Image Source="Binding Path=OutfitImageString, UpdateSourceTrigger=PropertyChanged"/>
C# URI 字符串,我想用它来判断 PNG 何时更改:
private string _OutfitImageString;
public string OutfitImageString
get return _OutfitImageString;
set
_OutfitImageString = value;
NotifyPropertyChanged("OutfitImageString");
每次我更改位图图片(它绑定到一个类的实例)时,我都会运行这个方法:
public void UpdateImage()
// new bitmap (transparent background by default)
Bitmap nb = new Bitmap(100, 110, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
// [ ... ] Create the Bitmap
// save to PNG to get a transparent background, every Person has a unique name
string saveAt = Directory.GetCurrentDirectory() + Name + "_outfit.png";
nb.Save(saveAt, System.Drawing.Imaging.ImageFormat.Png);
// notify that we changed the image (even tho the URI string is the same)
OutfitImageString = saveAt;
这一行一旦运行 2. 时间就会产生一个错误:
nb.Save(saveAt, System.Drawing.Imaging.ImageFormat.Png);
异常类型 -2147467259 GDI+ 中的 Allgemeiner Fehler。溢出异常:System.Runtime.InteropServices.ExternalException (0x80004005):GDI+ 中的 Allgemeiner Fehler。 bei System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams) bei System.Drawing.Image.Save(String filename, ImageFormat format)
我之前存储了 Bitmap 的 BitmapSource 并绑定到那个,这曾经完美地工作(只是背景不透明)。
此外,由于这些图像是临时的,我不喜欢一直保存它们:/
感谢您的帮助,很抱歉描述有点混乱...如果您需要更多详细信息,请写!
【问题讨论】:
以前不透明,现在不更新-.- 错误是什么? 将位图保存到文件有什么特别的原因吗?您也可以直接从 Bitmap 转换为 BitmapSource。您可能会直接创建一个 BitmapSource,从而完全避免使用 Bitnap。顺便说一句,当您通过内置类型转换从字符串加载 BitmapImage 时,WPF 会保持图像文件打开。 @Bijan,错误是:异常类型 -2147467259 GDI+ 中的 Allgemeiner Fehler。溢出异常:System.Runtime.InteropServices.ExternalException (0x80004005):GDI+ 中的 Allgemeiner Fehler。 bei System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams) bei System.Drawing.Image.Save(String filename, ImageFormat format) @Clemens 我必须使用 PNG 才能使透明背景工作。当我使用 BitmapSource 时它是黑色的 【参考方案1】:完全不需要保存位图文件。
将属性的类型从字符串更改为 ImageSource
private ImageSource _OutfitImage;
public ImageSource OutfitImage
get return _OutfitImage;
set
_OutfitImage = value;
NotifyPropertyChanged(nameof(OutfitImage));
并如下所示绑定到它(设置UpdateSourceTrigger=PropertyChange
毫无意义)。
<Image Source="Binding Path=OutfitImage"/>
然后像这样赋值:
OutfitImage = BitmapToBitmapSource(nb);
...
public static BitmapSource BitmapToBitmapSource(System.Drawing.Bitmap bitmap)
var bitmapImage = new BitmapImage();
using (var stream = new MemoryStream())
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Position = 0;
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = stream;
bitmapImage.EndInit();
return bitmapImage;
【讨论】:
@Clemes 谢谢!你是个巫师 :D,我只需要添加: System.Windows.Application.Current.Dispatcher.Invoke(new Action(() => UpdateImage();));让它毫无例外地工作:D以上是关于在运行时更新 PNG 图像会引发 GDI+ 溢出异常的主要内容,如果未能解决你的问题,请参考以下文章
当字节数组的源是 jpg 时,从存储的字节数组创建位图并保存到磁盘会引发 GDI+ 异常