我正在尝试在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,最后加载到Image中,然后将其重新添加到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[] to BitmapImage in silverlight
作为最后一步,我只需再次创建一个Image并将其添加到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 from stream throws exception (Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))),碰巧有相同的异常,但正如我读到的那样,似乎只有当他上传大量图像时他才会遇到这个问题,而且对于他来说,只需要一点点图像就可以了。所以我仍然对如何解决这个问题一无所知?
你们可能有任何建议吗?谢谢!
答案 0 :(得分:3)
我认为您正在崩溃,因为您重建图像的字节数组是ARGB值的“原始”数组,而Source
属性期望构成有效的字节流PNG或JPG文件。原始ARGB数据极不可能是有效的PNG或JPG文件,因为它几乎肯定不包含每种格式所需的有效标头。
我无法重现崩溃;相反,我运行代码时创建的BitmapImage
PixelWidth
和PixelHeight
都为零。这可能是因为我正在使用与您正在使用的图像不同的图像。无论哪种方式,崩溃或没有崩溃,这都不是行为。
如果要将修改后的数据加载回Image
,则无需创建byte
数组。只需从Image
对象创建WriteableBitmap
:
Image modifiedImage = new Image()
{
Source = writeableBitmap,
Stretch = Stretch.None
};
我用它来添加原始图像下方的图像副本。修改后的图像与原始图像相比具有“褪色”外观,正如我将所有alpha通道值减半所预测的那样。
如果确实需要将字节数组转换回图像,可以在WriteableBitmapEx中使用FromByteArray
扩展方法。然后,您可以如上所述创建Image
。
答案 1 :(得分:1)
我之前遇到过这个例外: