1

我很难转换MemoryStreamBitmapImage. 关于类似情况有很多问题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加载完毕,我就开始使用它。我实例化 a Bitmap,以便我可以将它用于Tessnet2相关工作,然后尝试实例化 a 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。如果我尝试将其关闭或对其执行任何操作,在将其分配为StreamSourceto之后DisplayImage,我会null在尝试执行此类操作的行上遇到异常。我什至尝试创建两个不同的流,看看是否是问题所在;但是,我得到了完全相同的行为。调试这是一种痛苦,考虑到它不指向任何特定的行。MemoryStream这和之间显然存在问题BitmapImage。有没有可能两者之间存在某种格式/转换问题,但MemoryStreamBitmap这种特殊情况下却没有?

我尝试了文件路径,将其保存MagickImage到文件中并将其加载到其中BitmapImageUri它完美地工作;但是,我希望能够在内存中执行此操作。顺便说一句,将位置设置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));
4

1 回答 1

0

Magick.NET 的Write()方法有一些 bug,所以我们必须使用ToBitmap().

image.ToBitmap().Save(ImageStream, System.Drawing.Imaging.ImageFormat.Bmp);
于 2018-09-15T01:43:08.393 回答