[英]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.