通过压缩“CCITT T.6”分离多页tiff非常慢

发布于 2024-09-01 08:28:14 字数 1173 浏览 2 评论 0原文

我需要分离多帧 tiff 文件,并使用以下方法:

public static Image[] GetFrames(Image sourceImage)
{
    Guid objGuid = sourceImage.FrameDimensionsList[0];
    FrameDimension objDimension = new FrameDimension(objGuid);
    int frameCount = sourceImage.GetFrameCount(objDimension);
    Image[] images = new Image[frameCount];
    for (int i = 0; i < frameCount; i++)
    {
        MemoryStream ms = new MemoryStream();
        sourceImage.SelectActiveFrame(objDimension, i);
        sourceImage.Save(ms, ImageFormat.Tiff);
        images[i] = Image.FromStream(ms);
    }
    return images;
}

它工作正常,但如果源图像使用 CCITT T.6 压缩进行编码,则分离 20 帧文件最多需要 15 秒

当使用标准压缩 (LZW) 将图像保存到单个文件时,LZW 文件的分离时间低于 1第二。

使用 CCITT 压缩保存也需要很长时间。

有没有办法加快这个过程?

编辑:

我测量了执行时间:

        sourceImage.SelectActiveFrame(objDimension, i);
        sourceImage.Save(ms, ImageFormat.Tiff);

这两个调用各占总处理时间的 50% 左右。 使用一个初始容量足以容纳所有图像的 MemoryStream 不会导致可测量的速度增益。 Image.FromStream 方法几乎不需要任何处理时间。

我需要单帧,因为我需要处理它们(纠偏、旋转等)。

如果有与我完全不同的方法,我会很高兴听到。

I need to separate multiframe tiff files, and use the following method:

public static Image[] GetFrames(Image sourceImage)
{
    Guid objGuid = sourceImage.FrameDimensionsList[0];
    FrameDimension objDimension = new FrameDimension(objGuid);
    int frameCount = sourceImage.GetFrameCount(objDimension);
    Image[] images = new Image[frameCount];
    for (int i = 0; i < frameCount; i++)
    {
        MemoryStream ms = new MemoryStream();
        sourceImage.SelectActiveFrame(objDimension, i);
        sourceImage.Save(ms, ImageFormat.Tiff);
        images[i] = Image.FromStream(ms);
    }
    return images;
}

It works fine, but if the source image was encoded using the CCITT T.6 compression, separating a 20-frame-file takes up to 15 seconds on my 2,5ghz CPU.(One core is at 100% during the process)

When saving the images afterwards to a single file using standard compression (LZW), the separation time of the LZW-file is under 1 second.

Saving with CCITT compression also takes very long.

Is there a way to speed up the process?

edit:

I have measured the execution times:

        sourceImage.SelectActiveFrame(objDimension, i);
        sourceImage.Save(ms, ImageFormat.Tiff);

These two calls each account for around 50% of the total processing time.
Using one MemoryStream with an initial capacity big enough for all images results in no measurable speed gain.
The Image.FromStream method takes barely any processing time.

I need the single frames because I need to process them(deskew, rotate, etc.).

If there is a completely different method than mine, I would be happy to hear it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白况 2024-09-08 08:28:14

根据您的情况,要做的第一件事就是衡量。

在我们弄清楚如何使其更快之前,当然,在我们通过优化使其变得更加复杂之前,我们需要知道哪些部分是缓慢的。幸运的是,您有一段非常短的代码,因此很容易添加您自己的计时代码,然后我们可以进行更明智的查看。

话虽如此,这里有一些不知情的建议:

  1. 我假设这些图像相当大并且都具有相同的尺寸,因此与其为每个图像创建一个新的内存流并动态增长它,为什么不构造一个 MemoryStream 这将足够大,然后将其用于所有这些,这将减少该方法创建的垃圾量并减少总体分配的数量。
  2. 您说您将其中一个核心的利用率设为 100%,因此我们应该尝试使用多个核心。您可以尝试将工作分成多个线程。也许有一个线程将帧保存到 MemoryStreams 中,另一个线程可以将它们加载到新图像中,它们可以通过工作队列进行通信。
  3. 你说你正在分割它,然后你又说你正在保存它,也许你可以直接保存,而不是在中间经过另一个图像对象。

The first thing to do in your situation would be to measure.

Before we can figure out how to make it faster, and certainly before we make it far more complicated with optimizations, we need to know what are the slow parts. luckily you have a very short piece of code so it would be pretty easy to just throw in your own timing code and then we can take a more informed look.

That being said here are a few uninformed pieces of advice:

  1. I assume that these images are fairly big and all have the same dimensions, therefore instead of making a new memory stream for each image and growing it dynamically why not construct a MemoryStream that will be big enough and then use that for all of them, this will decrease the amount of garbage that the method creates and decrease the number of overall allocations.
  2. You said you are pegging one of your cores at 100%, so we should probably try to use more than one core. You could try to split the work across multiple threads. Maybe have one thread save the frames into MemoryStreams and another can load them into new images, they could communicate via a work queue.
  3. You say you are splitting it and then later you say that you are saving it again, maybe you can just save directly instead of going through another image object in the middle.
濫情▎り 2024-09-08 08:28:14

这似乎是 Windows 7 上 GDI+ 的问题。

我在运行 Windows XP 的速度慢得多的计算机上运行了一个示例程序,并且在压缩图像上获得了比 Windows 7 更好的性能(大约快 2-3 倍)

It seems to be a problem with GDI+ on Windows 7.

I ran a sample program on a much slower machine with Windows XP, and got much better performance on compressed images than I got with Windows 7(around 2-3 times faster)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文