MemoryStream в BitmapImage
Я немного затрудняюсь с конвертацией MemoryStream
в BitmapImage
, Есть много вопросов по SO
Что касается подобных ситуаций, но, попробовав все на них, я не смог это исправить, поэтому я обращаюсь к вам. Обратите внимание, что я работаю с Magick.NET
(ImageMagick.NET) и Tessnet2
- это то, что является частью этого кода.
я использую Bitmap
класс для выполнения большей части работы в Magick.NET и Tessnet2. BitmapImage
используется для отображения целей.
Сначала я загружаю PDF и извлекаю обрезанное растровое изображение с его первой страницы:
public Task PdfToBmp(string path)
{
return Task.Run(() =>
{
using (var image = new MagickImage())
{
MagickNET.SetGhostscriptDirectory("./");
var settings = new MagickReadSettings
{
Density = new MagickGeometry(300, 300),
FrameCount = 1
};
image.Read(path, settings);
image.Crop(new MagickGeometry(1850, 200, 600, 140));
// ImageStream is a MemoryStream property.
ImageStream = new MemoryStream();
image.Write(ImageStream, MagickFormat.Bmp);
ImageStream.Position = 0;
}
});
}
Именно тогда я сохраняю растровое изображение в MemoryStream
, Однажды MemoryStream
загружен, я перехожу к работе с ним. Я создаю экземпляр Bitmap
так что я могу использовать его для Tessnet2
связанная работа, а затем попытаться создать экземпляр BitmapImage
,
public Task DoOcr()
{
if (ImageStream == null)
{
return null;
}
TargetImage = new Bitmap(ImageStream);
ImageStream.Position = 0;
// ----------------------- Problem Area ----------------------- //
DisplayImage = new BitmapImage();
DisplayImage.BeginInit();
DisplayImage.StreamSource = ImageStream;
DisplayImage.CacheOption = BitmapCacheOption.OnLoad;
DisplayImage.EndInit();
//ImageStream.Close();
// ------------------------------------------------------------ //
return Task.Run(() =>
{
var ocr = new Tesseract();
ocr.Init("tessdata", "eng", false);
var results = ocr.DoOCR(TargetImage, Rectangle.Empty);
Dispatcher.Invoke(() =>
{
Results = new ObservableCollection<Word>(results);
});
});
}
Вот где у меня проблема. Без этого DisplayImage
Блок, программа работает нормально, и я просто не получаю отображаемое изображение. Я даже могу спасти Bitmap
(TargetImage
) в файл без проблем. Однако с DisplayImage
блок, я получаю System.NullReferenceException
:
System.NullReferenceException occurred
_HResult=-2147467261
_message=Object reference not set to an instance of an object.
HResult=-2147467261
IsTransient=false
Message=Object reference not set to an instance of an object.
Source=System
StackTrace:
at System.Uri.CreateThisFromUri(Uri otherUri)
InnerException:
Я не могу точно определить, где именно это происходит, потому что ImageStream
объект выглядит "хорошо" при осмотре. Он содержит данные и находится в позиции 0. Если я попытаюсь закрыть его или сделать что-нибудь с ним, после назначения его в качестве StreamSource
в DisplayImage
Я получаю null
исключение на линии, которая пытается выполнить такое действие. Я даже попытался создать два разных потока, чтобы увидеть, в этом ли проблема; однако я получал точно такое же поведение. Отладка это своего рода боль, учитывая, что она не указывает ни на одну конкретную строку. Там, очевидно, проблема между этим MemoryStream
а также BitmapImage
, Возможно ли, что между ними есть какая-то проблема форматирования / преобразования, но не между MemoryStream
а также Bitmap
в этой конкретной ситуации?
Я пробовал файл маршрута, куда я сохраняю MagickImage
в файл и загрузить его в BitmapImage
через Uri
и это сработало без нареканий; Тем не менее, я хотел бы иметь возможность выполнить это в памяти. Кстати, установив положение на 0
на MemoryStream, похоже, тоже не влияет Bitmap
(загружается правильно) или BitmapImage
(то же исключение).
Временное исправление, которое я сейчас использую, - сделать DisplayImage
BitmapSource
, скорее, чем BitmapImage
:
DisplayImage = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
TargetImage.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,
BitmapSizeOptions.FromWidthAndHeight(TargetImage.Width, TargetImage.Height));
1 ответ
Магия.NET Write()
Метод имеет некоторые ошибки, поэтому мы должны использовать ToBitmap()
,
image.ToBitmap().Save(ImageStream, System.Drawing.Imaging.ImageFormat.Bmp);