LZW压缩方法没有用imagick压缩TIFF图像

时间:2014-03-31 07:29:48

标签: php imagick

我有以下代码来操作和压缩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压缩导致多条带tiff图像,而itextsharp不支持这种图像。

所以我的问题有两个可能的答案。答案中的任何一个都适用于我

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

2 个答案:

答案 0 :(得分: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图像,它们可能有效,但很可能不会。
不知道Paul 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

答案 1 :(得分:0)

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

**输入文件:jpeg 500kb。  * jpeg in tiff 1.25mb  * ZIP 2.0mb  * LZW 2.5mb  * LRE 3.2mb

有一件事 - 不要为tiff压缩设置质量,因为它是无丢失的格式 - 它只是忽略它(设置为100来计算)。您可以将其设置为tiff的jpeg压缩 - 没有其他。

但您可以做的是在保存之前添加行$im->stripImage();。这将从文件中删除一些信息 - 可能会使它变小。

另外请检查我的Imagick版本:ImageMagick 6.7.7-7 2012-06-21 Q16并且效果很好。