簡體   English   中英

C#Windows 8 Store(Metro,WinRT)字節數組到BitmapImage

[英]C# Windows 8 Store (Metro, WinRT) Byte array to BitmapImage

我正在開發一個將過濾器應用於圖像的Windows 8 Metro應用程序。 我有一個網絡版的應用程序,並希望移植它。 但是我們都知道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;
    }

這個拋出以下異常:

mscorlib.dll中出現“System.Exception”類型的異常,但未在用戶代碼中處理

附加信息:找不到該組件。 (來自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;
    }

這是我的第一個答案..希望它會有所幫助。

我有完全相同的問題,我花了6個多小時試圖解決這個問題。 這就是我想出的:你說的是對的。 有2個方法將圖像轉換為byteArray:

第一個方法(你的)

        public async Task<byte[]> ImageFileToByteArrayAsync(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();
    }

第二個方法

        public async Task<byte[]> ImageFileToByteArrayAsync(StorageFile file)
    {
        var inputStream = await file.OpenSequentialReadAsync();
        var readStream = inputStream.AsStreamForRead();
        var buffer = new byte[readStream.Length];
        await readStream.ReadAsync(buffer, 0, buffer.Length);
        return buffer;
    }

如果你使用第二個aproach解碼pic,沒有像素,這個轉換器將工作:

public class ByteArrayToImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value == null || !(value is byte[]))
            return null;

        using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
        {
            using (DataWriter writer = new DataWriter(stream.GetOutputStreamAt(0)))
            {
                writer.WriteBytes((byte[])value);
                writer.StoreAsync().GetResults();
            }
            BitmapImage image = new BitmapImage();
            image.SetSource(stream);
            return image;
        }
    }
    public object ConvertBack(object value, Type targetType, object parameter, string language)                                                                         
    {
        throw new NotImplementedException();
    }

對於第一個aproach,你需要使用WriteableBitmap,如你所說。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM