Silverlight:将字节[]转换为BitmapImage以"catastrophic failure"结尾



我正在尝试在Silverlight中修改BitmapImage,但碰巧遇到了"灾难性故障"!

首先,我加载一个图像并将其添加到 LayoutRoot。

BitmapImage source = new BitmapImage(new Uri("image.jpg", UriKind.Relative));
Image imageElement = new Image();
imageElement.Name = "imageElement";
imageElement.Source = source;
imageElement.Stretch = Stretch.None;
LayoutRoot.Children.Add(imageElement);

这工作正常,图像正确显示在屏幕上。

接下来,我想修改图像(例如:单击按钮后)。

在按钮单击方法中,首先,我从 LayoutRoot 中获取图像,然后使用 WriteableBitmap 类对其进行修改:

Image imageElement = (Image) LayoutRoot.Children[1];
WriteableBitmap writeableBitmap = new WriteableBitmap(imageElement, null);
writeableBitmap.ForEach((x,y,color) => Color.FromArgb((byte)(color.A / 2), color.R, color.G, color.B));

接下来,我使用给定的方法将其保存到字节数组缓冲区中:

byte[] buffer = writeableBitmap.ToByteArray();  

这看起来也不错。缓冲区显示所有 ARGB 值,甚至 alpha 值也是通常值的一半,即 127,就像它应该的那样!

在下一步中,我想将修改后的数据加载回BitmapImage,最后加载到图像中,然后将其再次添加到LayoutRoot中:

BitmapImage modifiedSource = null;
try
{
    using (MemoryStream stream = new MemoryStream(buffer))
    {
        stream.Seek(0, SeekOrigin.Begin);
        BitmapImage b = new BitmapImage();
        b.SetSource(stream);
        modifiedSource = b;
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.ToString());
}

我在这里找到了这个代码片段:byte[] 到 BitmapImage in silverlight

作为最后一步,我将再次创建一个图像并将其添加到LayoutRoot中(就像我一开始所做的那样:

Image modifiedImageElement = new Image();
modifiedImageElement.Name = "newImageElement";
modifiedImageElement.Source = modifiedSource;
modifiedImageElement.Stretch = Stretch.None;
LayoutRoot.Children.Add(modifiedImageElement);

但是最后一部分从未达到,因为发生了"灾难性故障"

b.SetSource(stream);

行,说:

{System.Exception: Catastrophic failure (Ausnahme von HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
   at MS.Internal.XcpImports.BitmapSource_SetSource(BitmapSource bitmapSource, CValue& byteStream)
   at System.Windows.Media.Imaging.BitmapSource.SetSourceInternal(Stream streamSource)
   at System.Windows.Media.Imaging.BitmapImage.SetSourceInternal(Stream streamSource)
   at System.Windows.Media.Imaging.BitmapSource.SetSource(Stream streamSource)
   at SilverlightApplication1.MainPage.button1_Click(Object sender, RoutedEventArgs e)}

我不知道出了什么问题。我在这里找到了一篇文章Silverlight:来自流的BitmapImage抛出异常(灾难性故障(来自HRESULT的异常:0x8000FFFF(E_UNEXPECTED))),碰巧有相同的异常,但是当我阅读它时,似乎他只有在上传大量图像时才遇到此问题,并且对于少量图像,它对他来说效果很好。所以我仍然不知道如何解决这个问题?

你们有什么建议吗?谢谢!

我认为您正在崩溃,因为您从中重建图像的字节数组是 ARGB 值的"原始"数组,而 Source 属性需要构成有效 PNG 或 JPG 文件的字节流。 原始 ARGB 数据极不可能是有效的 PNG 或 JPG 文件,因为它几乎肯定不包含每种格式所需的有效标头。

我无法重现崩溃;相反,当我运行代码时创建的BitmapImage PixelWidthPixelHeight都为零。 这很可能是因为我使用的图像与您正在使用的图像不同。 无论哪种方式,崩溃或不崩溃,都不是期望的行为。

如果要将修改后的数据加载回Image,则无需创建byte数组。 只需从WriteableBitmap对象创建一个Image

        Image modifiedImage = new Image()
        {
            Source = writeableBitmap,
            Stretch = Stretch.None
        };

我用它来在原始图像下方添加图像的副本。 与原始图像相比,修改后的图像具有"褪色"的外观,这正是我将所有 alpha 通道值减半时所期望的。

如果确实需要将字节数组转换回图像,则可以使用 WriteableBitmapEx 中的FromByteArray扩展方法。 然后,您可以如上所述创建Image

我之前遇到过这个异常:

  1. 将不受支持的图像类型传递给 silverlight 时:BMP、...仅支持 JPG 和 PNG。请参阅 MSDN
  2. 传递不正确的数据(不是全部流或格式不正确)时

最新更新