我正在开发一个将滤镜应用于图像的 Windows 8 Metro 应用程序。我有该应用程序的 Web 版本并想移植它。但众所周知,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[]
中。我猜测里面的 pixelData 格式无效,所以我尝试将其更改为 RGBA,但这也无济于事。 BitmapImage 的 PixelHeight 和 PixelWidth 也为 0。
最佳答案
这对我有用,
private async Task<BitmapImage> ByteArrayToBitmapImage(byte[] byteArray)
{
var bitmapImage = new BitmapImage();
var stream = new InMemoryRandomAccessStream();
await stream.WriteAsync(byteArray.AsBuffer());
stream.Seek(0);
bitmapImage.SetSource(stream);
return bitmapImage;
}
关于C# Windows 8 Store (Metro, WinRT) 字节数组到 BitmapImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17107576/