简体   繁体   English

libtiff.net将多页tiff拆分为单页tiff图像

[英]libtiff.net split multipage tiff into single page tiff images

I'm trying to use LibTiff.Net to split a multipage TIFF image into single page TIFF images. 我正在尝试使用LibTiff.Net将多页TIFF图像拆分为单页TIFF图像。

I am building a TIFF splitting intermediary between two systems. 我正在建立两个系统之间的TIFF拆分中介。 I will receive the multipage TIFF image as a stream and then split it up into individual page TIFF image files and return them as a list of byte arrays. 我将以流的形式接收多页TIFF图像,然后将其拆分为单独的页面TIFF图像文件,并将其作为字节数组列表返回。

I make a call to a web service that returns the multipage TIFF image as a stream. 我调用了一个Web服务,该服务将多页TIFF图像作为流返回。 I need to extract each page as a separate TIFF image to return them as a list of byte arrays. 我需要将每个页面提取为单独的TIFF图像,以将它们作为字节数组列表返回。 I've seen the TiffCP utility that can split a multipage image on disk into separate TIFF image files on disk. 我已经看到了TiffCP实用程序,该实用程序可以将磁盘上的多页图像拆分为磁盘上的单独TIFF图像文件。 I don't want to write anything to disk during this operation if I can avoid it. 如果可以避免,我不想在此操作期间向磁盘写入任何内容。

I also don't want to decode any of the image content of the input image because that would waste processing time. 我也不想解码输入图像的任何图像内容,因为那样会浪费处理时间。

Is this possible with LibTiff.Net? LibTiff.Net是否可能?

UPDATED @bobrovsky - thank you for your suggestion. @bobrovsky 更新 -谢谢您的建议。

Here is what I've tried. 这是我尝试过的。 I took the Copier class out of the source code for TiffCP to use it in my project with zero edits. 我从TiffCP的源代码中删除了Copier类,以在零编辑的情况下在我的项目中使用它。 The code below is how I'm using it. 下面的代码是我如何使用它。 When this code completes execution the MemoryStream objects that should have the entire single page TIFF image inside them are all exactly 1,282 bytes in size. 当此代码完成执行时,应在其中包含整个单页TIFF图像的MemoryStream对象的大小都完全为1,282字节。 It seems like I'm missing a function call that forces the TIFF image data to be written to the underlying store (in this case the MemoryStream). 似乎我缺少一个强制将TIFF图像数据写入底层存储(在本例中为MemoryStream)的函数调用。 I've included a call to Flush() to try fixing this issue but it had no affect. 我已经包含了对Flush()的调用,以尝试解决此问题,但没有任何效果。 Does anyone know what I'm missing? 有人知道我在想什么吗?

using (memoryStream)
{
    memoryStream.Position = 0;
    using (Tiff image = Tiff.ClientOpen("iqdoc", "r", memoryStream, new TiffStream()))
    {
        int totalPages = image.NumberOfDirectories();
        for (int i = 0; i < totalPages; i++)
        {
            image.SetDirectory((short)i);
            using (var ms = new MemoryStream())
            using (Tiff page = Tiff.ClientOpen("page", "w", ms, new TiffStream()))
            {
                var c = new Copier();
                c.m_compression = c.m_defcompression; // THIS WAS MISSING
                if (!c.Copy(image, page) || !page.WriteDirectory())
                    throw new ApplicationException("Failed to extract page from document for presentation.");

                FieldValue[] field = image.GetField(TiffTag.IMAGEWIDTH);
                int width = field[0].ToInt();

                field = image.GetField(TiffTag.IMAGELENGTH);
                int height = field[0].ToInt();

                page.Flush();

                pages.Add(new
                {
                    Height = height,
                    Width = width,
                    PageBytes = Convert.ToBase64String(ms.ToArray()),
                });

                c = null;
            }
        }
    }
}

Thanks! 谢谢!

Yes, it's possible. 是的,有可能。 TiffCP does this. TiffCP会这样做。

You can take TiffCP code and adapt it to your needs (change the way it stores output). 您可以采用TiffCP代码并使其适应您的需求(更改其存储输出的方式)。

You can also come up with other ideas and implement one of those. 您还可以提出其他想法并实施其中之一。

You might not get a complete working solution in an answer on this site. 您可能无法在此站点的答案中获得完整的工作解决方案。

EDIT: 编辑:

Your code is mostly ok, but you should only access bytes of the memory stream after Tiff has finished writing to it. 您的代码大部分都可以,但是您应该仅在Tiff完成写入后访问内存流的字节。

Unfortunately, Tiff closes memory stream in it's Dispose and Close methods. 不幸的是, Tiff在其DisposeClose方法中关闭了内存流。 You might try two approaches to overcome the issue: 您可以尝试两种方法来解决此问题:

  • Call Tiff.WriteDirectory before accessing bytes in the memory stream. 在访问内存流中的字节之前,请先调用Tiff.WriteDirectory This should be ok, but you might get an incomplete TIFF in the stream. 应该是好的,但你可能会流不完整的TIFF。
  • Create your own stream (based on the System.IO.MemoryStream ) which overloads Close method with an empty implementation and use this stream instead of MemoryStream . 创建您自己的流(基于System.IO.MemoryStream ),该流将用空实现重载Close方法,并使用此流而不是MemoryStream Access bytes in this stream after Tiff is disposed. 放置Tiff之后,访问此流中的字节。

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

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