C# Windows 8 Store (Metro, WinRT) 字节数组到 BitmapImage

标签 c# microsoft-metro bytearray windows-store-apps bitmapimage

我正在开发一个将滤镜应用于图像的 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/

相关文章:

c# - 在 C# 中使用正则表达式拆分字符串上的标记

c# - 如何获取以空格分隔的输入

c# - 如何安装最新的服务栈开源dll

windows-8 - 如何在 Windows 8 Metro 应用程序 C# 中将保存缩略图图像存储在设备中

将 C 字符串转换为二进制表示

c# - 使用泛型重载运算符

c# - 如何在源数据更改时更新数据绑定(bind)组合框?

deployment - 如何诊断 Metro 应用程序部署错误?

java - 将 assertArrayEquals() 与通配符一起使用?

character-encoding - 钛 ByteArray 图像 Blob