【问题标题】:LZW compression method not compressing TIFF image with imagickLZW 压缩方法不使用 imagick 压缩 TIFF 图像
【发布时间】:2014-03-31 07:29:47
【问题描述】:

我有以下代码来操作和压缩 TIFF 图像。

<?php

try{
    $imagesrc = "C:\\server\\www\\imagick\\src.tif";
    $imagedestination = "C:\\server\\www\\imagick\\converted.tif";
    $im=new Imagick();
    $im->readImage($imagesrc); //read image for manipulation
    $im->setImageColorSpace(Imagick::COLORSPACE_CMYK);

    $im->setImageDepth(8); //8 Bit

    $im->setImageResolution(300,300); //set output resolution to 300 dpi
    $im->setImageUnits(1); //0=undefined, 1=pixelsperInch, 2=PixelsPerCentimeter
    $im->setImageCompression(Imagick::COMPRESSION_LZW);
    $im->setImageCompressionQuality(80);
    $im->writeImage($imagedestination);
    $im->clear();
    $im->destroy();
    $im=NULL;
}catch(ImagickException $e){
     echo "Could not convert image  - ".$e->getMessage();
}
?>

源图像为 19MB。当我使用此代码时,生成的 TIF 图像大约为 25MB。也就是说,代码根本没有压缩图像。其他压缩方法也对生成的 TIFF 文件没有影响,但是如果我使用压缩方法Imagick::COMPRESSION_JPEG,生成的图像为 2MB

我无法使用 JPEG 压缩,因为我使用带有 itextsharp 的生成 TIFF 图像嵌入 PDF。 JPEG 压缩会产生 itextsharp 不支持的多条 tiff 图像。

所以我的问题有两种可能的答案。任何一个答案都对我有用

  1. 如何有效压缩tif?
  2. 如何将多条 tif 图像转换为单条。

谢谢

【问题讨论】:

  • The source image is 19MB - 这听起来像是一个相当大的图像,因为 COMPRESSION_LZW/q=0.8 会生成更大的文件管理器。图片的尺寸是给定的,不能更改?
  • 你的图片尺寸是多少?
  • @VolkerK,我们可以在质量上妥协,但不能在图像尺寸上妥协。图像尺寸为 3655x3735 像素。源图像的尺寸和大小可能会因用户上传的内容而异。
  • 抱歉唠叨:in a quality but not in image dimension tiff 格式可以存储 dpi - 它真的是您需要保持不变的像素大小还是输出尺寸(作为像素/dpi)?我看到您将 dpi 设置为 300,但也可以将其设置为 72 吗?
  • @VolkerK,像素大小需要保持不变。这意味着,我们可以更改 DPI,但我也尝试过,我将输出 DPI 从 300 更改为 170,文件大小没有变化。

标签: php imagick


【解决方案1】:

摆弄 php-imagick 让我无处可去,所以我尝试了Magick.NET
只有通过设置rows-per-strip 定义一个大于图像中线条的数字(即#strips=1),iTextSharp 才接受带有 CompressionMethod.JPEG 的图像。
但它仍然无法正常工作。我计算机上的所有图像查看器都能正确渲染图像,但在 PDF 文档中它已损坏。
我发现了这个论坛条目http://itext-general.2136553.n4.nabble.com/TIFF-with-color-pages-COMPRESS-JPEG-problem-td3686051.html

iText 并不真正支持 Jpeg 压缩的 tiff 图像,它们可能有效,但很可能不会。
不知道 Paulo Soares-3 的帖子有多权威,但我放弃了。
因此:这不是一个答案。但也许你也想摆弄 .NET 端口,所以这是我的测试代码 - 祝你好运:
using iTextSharp.text;
using iTextSharp.text.pdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace imagick_itext_test
{
    class Program
    {
        static Image getNormalizedImage(string path)
        {
            Image rv;
            using (MemoryStream mems = new MemoryStream())
            {
                using (ImageMagick.MagickImage image = new ImageMagick.MagickImage(path))
                {
                    image.Format = ImageMagick.MagickFormat.Tiff;
                    image.ResolutionUnits = ImageMagick.Resolution.PixelsPerInch;
                    image.Depth = 300;
                    image.BitDepth(8); // for printing you said? ;-)
                    image.Adjoin = false; // is there multi-image in jpeg anyway?
                    image.Interlace = ImageMagick.Interlace.Jpeg; // try Interlace.Plane and Interlace.No
                    image.CompressionMethod = ImageMagick.CompressionMethod.JPEG; // everything's fine when using .LZW here
                    image.Quality = 35;  // 85, 80 not even 50 got me significant reduction in file size (src size=18MB)
                    //image.SetDefine(ImageMagick.MagickFormat.Tiff, "rows-per-strip", image.Height.ToString());
                    image.SetDefine(ImageMagick.MagickFormat.Tiff, "rows-per-strip", "8192");
                    image.Strip(); // remove additional data, e.g. comments
                    image.Write(mems);
                }

                // store the tiff(jpeg) image for inspection
                using (FileStream fos = new FileStream(@"c:\temp\so_conv.tiff", FileMode.Create) )
                {
                    mems.Position = 0;
                    mems.CopyTo(fos);
                }
                mems.Position = 0;
                rv = Image.GetInstance(mems);
                //rv.ScalePercent(24f); // works for me ...
            }
            return rv;
        }

        static void Main(string[] args)
        {
            using (Document doc = new Document())
            {
                using (PdfWriter w = PdfWriter.GetInstance(doc, new FileStream(@"c:\temp\so_pdf_test.pdf", FileMode.Create)))
                {
                    doc.Open();
                    doc.SetMargins(50, 50, 50, 50);
                    doc.Add(new Paragraph("SO Image Test"));
                    doc.Add(getNormalizedImage(@"c:\temp\src.tif"));
                    doc.Close();
                }
            }
        }
    }
}

VS2012 - .net 4.5,ImageMagick-6.8.8-10-Q16-x64-static.exe
Magick.NET 和 iTextSharp 都已通过 NuGet 添加到项目中:

  • iTextSharp 5.50
  • Magick.NET-Q16-x64 6.8.8.901

【讨论】:

    【解决方案2】:

    根据我的测试,最好在 TIFF 中省略 JPEG = 是最小的。 然后是 ZIP 压缩,然后是 LZW,然后是 RLE。

    **输入文件:jpeg 500kb。 * tiff 中的 jpeg 1.25mb * 邮编 2.0mb * LZW 2.5mb * LRE 3.2mb

    有一件事 - 不要为 tiff 压缩设置质量,因为它是无损格式 - 它只是忽略它(设置为 100 用于计数)。您可以将其设置为 tiff 的 jpeg 压缩 - 仅此而已。

    但你可以做的是在保存之前添加行$im-&gt;stripImage();。这会从文件中删除一些信息——也许它会让你觉得文件更小。

    另外请检查您的 Imagick 版本,我是:ImageMagick 6.7.7-7 2012-06-21 Q16,它运行良好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      相关资源
      最近更新 更多