简体   繁体   English

MemoryStream到BitmapImage

[英]MemoryStream to BitmapImage

I am having a bit of a hard time converting MemoryStream into BitmapImage . 我很难将MemoryStream转换为BitmapImage There are a lot of questions on SO regarding similar situations, but after trying everything on them, I've been unable to fix this, so I turn to you. 上有很多问题SO关于类似的情况,但对他们的一切努力之后,我一直无法解决这个问题,让我转交给你。 Note that I'm working with Magick.NET (ImageMagick.NET) and Tessnet2 -- that is what some of that code is. 请注意,我正在使用Magick.NET (ImageMagick.NET)和Tessnet2这就是其中一些代码。

I use Bitmap class to do most of the work in Magick.NET and Tessnet2. 我使用Bitmap类在Magick.NET和Tessnet2中完成大部分工作。 BitmapImage is used for displaying purposes. BitmapImage用于显示目的。

First, I load up the PDF and extract a cropped bitmap from its first page: 首先,我加载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;
        }
    });
}

That is when I save the bitmap into the MemoryStream . 那就是当我将位图保存到MemoryStream Once I have MemoryStream loaded up, I move onto working with it. 加载MemoryStream后,便开始使用它。 I instantiate a Bitmap , so that I may use it for Tessnet2 related work and then try to instantiate a BitmapImage . 我实例化了一个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);
        });
    });
}

This is where I'm having a problem. 这是我遇到的问题。 Without that DisplayImage block, the program runs fine and I just don't get the displayed image. 没有该DisplayImage块,该程序可以正常运行,而我只是无法获得显示的图像。 I'm even able to save the Bitmap ( TargetImage ) to a file with no problems. 我什至可以将BitmapTargetImage )保存到没有问题的文件中。 However, with the DisplayImage block, I get System.NullReferenceException : 但是,使用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: 

I'm unable to pinpoint where it occurs exactly, because the ImageStream object looks "fine" upon inspection. 我无法确切指出它的确切位置,因为经过检查, ImageStream对象看起来“很好”。 It contains data and is at position 0. If I try to close it, or do anything with it, after assigning it as the StreamSource to DisplayImage , I get a null exception on the line that attempts to perform such action. 它包含数据,并且位于位置0。如果将其分配为DisplayImageStreamSource后,尝试关闭它或对其执行任何操作,则在尝试执行此类操作的行上会得到一个null异常。 I even tried creating two different streams, to see if that's the problem; 我什至尝试创建两个不同的流,以查看是否是问题所在。 however, I was getting the exact same behavior. 但是,我得到了完全相同的行为。 Debugging this is kind of a pain, considering it doesn't point to any one specific line. 考虑到它并不指向任何特定的行,调试它是一种痛苦。 There's obviously an issue between this MemoryStream and BitmapImage . 在此MemoryStreamBitmapImage之间显然存在一个问题。 Could it be possible that there's some sort of format/conversion problem between the two, but not between MemoryStream and Bitmap in this particular situation? 在这种特殊情况下,两者之间是否可能存在某种格式/转换问题,而在MemoryStreamBitmap之间却没有?

I tried the file route, where I save MagickImage to a file and load it up into BitmapImage through Uri and it worked flawlessly; 我尝试了文件路由,将MagickImage保存到文件中,然后通过Uri其加载到BitmapImage ,并且运行正常。 however, I would like to be able to perform this in-memory. 但是,我希望能够在内存中执行此操作。 By the way, setting position to 0 on the MemoryStream did not seem to affect either Bitmap (loads properly) or BitmapImage (same exception). 顺便说一句,在MemoryStream上将position设置为0似乎不会影响Bitmap (正确加载)或BitmapImage (相同的异常)。

The temporary fix I currently use is to make DisplayImage a BitmapSource , rather than BitmapImage : 我当前使用的临时修复方法是将DisplayImageBitmapSource而不是BitmapImage

DisplayImage = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
    TargetImage.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,
    BitmapSizeOptions.FromWidthAndHeight(TargetImage.Width, TargetImage.Height));

Magick.NET的Write()方法存在一些错误,因此我们必须使用ToBitmap()

image.ToBitmap().Save(ImageStream, System.Drawing.Imaging.ImageFormat.Bmp);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM