WatsMyName
WatsMyName

Reputation: 4478

LZW compression method not compressing TIFF image with imagick

I have following code to manipulate and compress the TIFF image.

<?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();
}
?>

The source image is 19MB. When I use this code, the resulting TIF image is around 25MB. That is, the code is not compressing image at all. Also other compression methods have no effect on resulting TIFF file but however if i use compression method Imagick::COMPRESSION_JPEG, the resulting image is 2MB

I can't use JPEG compression, as I m using resulting TIFF image with itextsharp to embed in PDF. JPEG compression results in multi-strip tiff image which is not supported by itextsharp.

So there are two possible answers to my question. And either of the answer will work for me

  1. How to effectively compress the tif?
  2. How to convert multi-strip tif image into single strip.

Thanks

Upvotes: 1

Views: 3299

Answers (2)

Seti
Seti

Reputation: 2314

From what i have testes its better to leave out JPEG in TIFF = is the smallest. Then there is ZIP compression and then LZW and then RLE.

**Input file: jpeg 500kb. * jpeg in tiff 1.25mb * ZIP 2.0mb * LZW 2.5mb * LRE 3.2mb

One thing - dont set Quality for tiff compression as it is loseless format - it just ignores it (sets to 100 for counting). You may set it for the jpeg compression for tiff - nothing other.

But what you could do is add the line $im->stripImage(); before saving. This will strip some information from the file - maybe it will make it smaller for you.

Also please check your Imagick version my is: ImageMagick 6.7.7-7 2012-06-21 Q16 and it works well.

Upvotes: 0

VolkerK
VolkerK

Reputation: 96159

Fiddling with php-imagick got me nowhere, so I tried Magick.NET.
Only by setting the rows-per-strip define a number larger than the lines in the image (i.e. #strips=1) iTextSharp accepted the image with CompressionMethod.JPEG.
But it's still not working. All the image viewers I have on my computer render the image correctly, yet in the PDF documents it's broken.
And I found this forum entry http://itext-general.2136553.n4.nabble.com/TIFF-with-color-pages-COMPRESS-JPEG-problem-td3686051.html :

Jpeg compressed tiff images are not really supported in iText, they may work but most probably not.
No idea how authoritative Paulo Soares-3's post is, but I give up.
Therefore: this is not an answer. But maybe you want to fiddle with the .NET port as well, so here's my test code - good luck :

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
Both Magick.NET and iTextSharp have been added via NuGet to the project:

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

Upvotes: 1

Related Questions