Я работаю над приложением Windows 8 Metro, которое применяет фильтры к изображениям. У меня есть веб-версия приложения и вы хотите его портировать. Но, как мы все знаем, у WinRT нет всех хороших вещей, которые .NET предоставляет в противном случае:/
В настоящее время я применяю фильтры для байтового массива, и я хочу сохранить его таким образом, потому что он очень быстрый! Поэтому в течение последних нескольких дней я искал способы конвертировать StorageFile в байт [], а затем байт [] в BitmapImage.
До сих пор мне удалось сделать первый (StorageFile to 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;
}
Это вызывает следующее исключение:
Исключение типа "System.Exception" произошло в mscorlib.dll, но не было обработано в коде пользователя
Дополнительная информация: Компонент не найден. (Исключение из 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;
}
И получите то же исключение, что и первая часть кода.
Я также пробовал несколько других способов, которые включают использование обычного потока, а затем преобразование в IRandomAccessStream, но они также не работали.
Все приведенные выше коды кажутся мне прекрасными. Поэтому я предполагаю, что проблема заключается в byte[]
. Я предполагаю, что формат pixelData внутри недействителен, поэтому я попытался изменить его на RGBA, но это тоже не помогло. Также PixelHeight и PixelWidth BitmapImage равны 0.