Невозможно загрузить Splat.IBitmap из MemoryStream
Я пытаюсь отобразить данные макета в растровое изображение независимо от платформы, возвращая Splat.IBitmap, и у меня возникают проблемы с выводом результатов. Мой код платформы WPF выглядит так:
MemoryStream stream = new MemoryStream();
try
{
RenderTargetBitmap target = new RenderTargetBitmap(1024, 1024, 300, 300, PixelFormats.Default);
PreviewView preview = new PreviewView(); // this does sizing and placement
target.Render(preview);
previewViewModel.Dispose();
BitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(target));
encoder.Save(stream);
stream.Flush();
IBitmap bitmap = BitmapLoader.Current.Load(stream, 1024, 1024).Result;
stream.Dispose();
return bitmap;
}
catch (Exception e)
{
// TODO: log error
return null;
}
finally
{
stream.Dispose();
}
Я продолжаю бить AggregateException
на BitmapLoader.Current.Load
вызов. Внутреннее исключение NotSupportedException
с сообщением No imaging component suitable to complete this operation was found.
Я не смог найти соответствующую документацию, чтобы объяснить, что это значит или что я делаю неправильно. В качестве теста я попытался сохранить кодировщик растрового изображения в FileStream
, который работал нормально.
РЕДАКТИРОВАТЬ
Было отмечено, что эта проблема может быть дубликатом этой проблемы. Они, безусловно, связаны, но в этом случае я хотел бы знать, почему сохранение в MemoryStream
не удается создать действительные данные изображения, где FileStream
работает.
РЕДАКТИРОВАТЬ 2
По запросу, вот исключения, которые я вижу в выводе:
Exception thrown: 'System.NotSupportedException' in PresentationCore.dll
Exception thrown: 'System.NotSupportedException' in PresentationCore.dll
Exception thrown: 'System.AggregateException' in mscorlib.dll
Внутренний NotSupportedException
из AggregateException
имеет это сообщение и трассировку стека:
No imaging component suitable to complete this operation was found.
at System.Windows.Media.Imaging.BitmapDecoder.SetupDecoderFromUriOrStream(Uri uri, Stream stream, BitmapCacheOption cacheOption, Guid& clsId, Boolean& isOriginalWritable, Stream& uriStream, UnmanagedMemoryStream& unmanagedMemoryStream, SafeFileHandle& safeFilehandle)
at System.Windows.Media.Imaging.BitmapDecoder.CreateFromUriOrStream(Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy uriCachePolicy, Boolean insertInDecoderCache)
at System.Windows.Media.Imaging.BitmapImage.FinalizeCreation()
at System.Windows.Media.Imaging.BitmapImage.EndInit()
at Splat.PlatformBitmapLoader.withInit(BitmapImage source, Action`1 block) in y:\\code\\paulcbetts\\splat\\Splat\\Xaml\\Bitmaps.cs:line 80
at Splat.PlatformBitmapLoader.<>c__DisplayClass2.<Load>b__0() in y:\\code\\paulcbetts\\splat\\Splat\\Xaml\\Bitmaps.cs:line 25
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
Хотя это исключение внутреннее NotSupportedException
есть только это сообщение, и нет трассировки стека:
The component cannot be found. (Exception from HRESULT: 0x88982F50)
1 ответ
Это не отвечает на мой первоначальный вопрос, поэтому я не приму это как правильный ответ, но я нашел более правильный способ справиться с тем, что я хотел. Я записывал в MemoryStream, потому что считал это необходимым, но все, что мне было нужно, - это выложить раскладанное представление в WPF и получить IBitmap, который я мог бы использовать в другом месте. Оказалось, что сделать это было легче, чем я это делал:
try
{
RenderTargetBitmap target = new RenderTargetBitmap(1024, 1024, 300, 300,
PixelFormats.Default);
PreviewView preview = new PreviewView(); // this does sizing and placement
target.Render(preview);
// HERE IS AN IMPORTANT BIT. This allows me to access the RenderTargetBitmap from
// another thread, for example if calling IBitmap.Save() which happens on another
// in a separate Task
target.Freeze();
previewViewModel.Dispose();
// HERE IS ANOTHER IMPORTANT BIT. There's no need to capture a frame and save to a
// Stream through an Encoder. Splat lets you create bitmaps from a native
// implementation
IBitmap bitmap = target.FromNative();
return bitmap;
}
catch (Exception e)
{
// TODO: log error
return null;
}