我正在开发一个Windows 8 Metro应用程序,该应用程序可以对图像应用滤镜。我有一个网络版的应用程序,想要移植到WinRT上。但众所周知,WinRT没有.NET提供的所有好东西 :/
目前,我正在对一个字节数组应用滤镜,并且希望保持这种方式,因为它非常快!因此,在过去的几天里,我一直在寻找将StorageFile转换为byte[],然后再将byte[]转换为BitmapImage的方法。
到目前为止,我已经成功地完成了第一个步骤(从StorageFile到byte[])。以下是我的代码:
public async Task<Byte[]> ImageFileToByteArray(StorageFile file)
{
IRandomAccessStream stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
PixelDataProvider pixelData = await decoder.GetPixelDataAsync();
return pixelData.DetachPixelData();
}
这段代码返回一个包含像素数据的byte[]
,格式为BGRA。
接下来是棘手的部分。我无法成功地将字节数组转换为BitmapImage。我已经到处搜索过,许多人建议使用WriteableBitmap,但对我没有什么帮助。我还找到了一些应该可以工作的代码片段......但它们并没有起作用。
我尝试过的一个解决方案是像这样使用InMemoryRandomAccessStream:
public async Task<BitmapImage> ByteArrayToBitmapImage(Byte[] pixels)
{
var stream = new InMemoryRandomAccessStream();
await stream.WriteAsync(pixels.AsBuffer());
stream.Seek(0);
var image = new BitmapImage();
await image.SetSourceAsync(stream);
return image;
}
这段代码引发了以下异常:
An exception of type 'System.Exception' occurred in mscorlib.dll but was not handled in user code我尝试使用以下代码替换了它:
Additional information: The component cannot be found. (Exception from HRESULT: 0x88982F50)
PixelDataProvider pixelData = await decoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
new BitmapTransform(),
ExifOrientationMode.IgnoreExifOrientation,
ColorManagementMode.DoNotColorManage);
但这对我没有好处,因为我不断地收到那个异常。
我也尝试了这个:
var bitmapImage = new BitmapImage();
var pixels = await ImageFileToByteArray(file);
ImageSource imgSource;
using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
{
using (DataWriter writer = new DataWriter(ms.GetOutputStreamAt(0)))
{
writer.WriteBytes(pixels);
await writer.StoreAsync();
}
await bitmapImage.SetSourceAsync(ms);
imgSource = bitmapImage;
}
并获得与第一段代码相同的异常。
我还尝试了几种其他方法,包括使用普通的Stream然后转换为IRandomAccessStream,但它们也没有起作用。
对我来说,上述所有代码都看起来很好。因此,我目前的猜测是问题出在byte[]
中。 我猜想像素数据内部的格式无效,因此我尝试将其更改为RGBA,但也没有帮助。另外,BitmapImage的PixelHeight和PixelWidth为0。