在运行时更新PNG图像会引发GDI +溢出异常

时间:2018-07-26 18:38:32

标签: c# wpf user-interface bitmap png

我制作了一个列表框,其中包含绑定了图像的项目(绑定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);
  

GDI +中的异常类型-2147467259 Allgemeiner Fehler。溢出异常:System.Runtime.InteropServices.ExternalException(0x80004005):GDI +中的Allgemeiner Fehler。 bei System.Drawing.Image.Save(字符串文件名,ImageCodecInfo编码器,EncoderParameters encoderParams)bei System.Drawing.Image.Save(字符串文件名,ImageFormat格式)

我先存储了位图的BitmapSource,然后又绑定到该位图,这曾经很完美(只是背景不透明)。

由于这些图像是临时图像,所以我不喜欢一直保存它们:/

感谢您的帮助,对不起,说明有点乱。如果需要更多详细信息,请写信!

1 个答案:

答案 0 :(得分:2)

根本不需要保存位图文件。

将属性的类型从字符串更改为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;
}