首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MemoryStream到BitmapImage

MemoryStream到BitmapImage
EN

Stack Overflow用户
提问于 2014-12-10 11:51:06
回答 1查看 2.1K关注 0票数 1

我在将MemoryStream转换为BitmapImage时遇到了一点困难。在SO上有很多关于类似情况的问题,但在尝试了所有这些问题后,我无法解决这个问题,所以我求助于您。请注意,我正在使用Magick.NET (ImageMagick.NET)和Tessnet2 --这就是其中的一些代码。

在Magick.NET和Tessnet2中,我使用Bitmap类完成大部分工作。BitmapImage用于显示目的。

首先,我加载PDF并从其第一页提取裁剪后的位图:

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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异常。我甚至尝试创建两个不同的流,看看这是否是问题所在;然而,我得到了完全相同的行为。考虑到它不指向任何特定的行,调试这是一种痛苦。显然,这个MemoryStreamBitmapImage之间存在问题。在这种特殊情况下,有没有可能在两者之间存在某种格式/转换问题,而不是在MemoryStreamBitmap之间?

我尝试了文件路径,我将MagickImage保存到一个文件中,并通过Uri将其加载到BitmapImage中,它可以完美地工作;但是,我希望能够在内存中执行此操作。顺便说一下,在MemoryStream上将position设置为0似乎既不会影响Bitmap (正确加载)也不会影响BitmapImage (相同的异常)。

我目前使用的临时修复方法是使DisplayImage成为BitmapSource,而不是BitmapImage

代码语言:javascript
复制
DisplayImage = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
    TargetImage.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,
    BitmapSizeOptions.FromWidthAndHeight(TargetImage.Width, TargetImage.Height));
EN

回答 1

Stack Overflow用户

发布于 2018-09-15 09:43:08

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

代码语言:javascript
复制
image.ToBitmap().Save(ImageStream, System.Drawing.Imaging.ImageFormat.Bmp);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27393037

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档