commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Gary Lucas (JIRA)" <>
Subject [jira] [Commented] (IMAGING-170) TIFF image gains significant size using TiffImageWriterLossless
Date Wed, 16 Sep 2015 13:34:45 GMT


Gary Lucas commented on IMAGING-170:


Lacking your original file, I can't be sure that I accurately diagnosed the problem, but I
took a look at the image that you posted and I have a couple of ideas. Unfortunately, my assessment
is that you have encountered unimplemented features in the Apache Commons Imaging library
and that some more work will be required to reduce the image size.

The sample image that you posted is photographic in nature. It is what is sometimes called
a "continuous tone image". In other words, color values are changing constantly from pixel
to pixel.  The most compact way to store a photographic image would, of course, be as a JPEG.
The TIFF standard does allow for internal compression using the JPEG methods. There is even
a tag for this in Apache Imaging's TiffConstants class. Unfortunately, the JPEG encoder is
not yet implemented and if you try to write an image using JPEG the TiffImageWriterLossless
throws an ImageWriteException.

So we're stuck using the Lempel-Ziv Compression (LZW) which is an excellent algorithm, but
depends on redundancy from pixel-to-pixel. The TIFF file you posted is based on LZW. Unfortunately,
due to its continuous tone nature, the LZW algorithm is only moderately successful in compressing

Which brings us to the other unimplemented feature from the TIFF standard. When writing images,
the TIFF standard permits the encoder to apply "predictive" modeling. Rather than storing
actual pixel values, it stores the differences between pixel values. Although the color values
in the image are varying continuously, they are varying at fixed rates. So while the values
from pixel to pixel are often different, the differences in the values are often the same.

I cannot be sure, but I believe that this is the problem you are facing in storing your image.
Apache Imaging is not exploiting the predictive modeling. For example, when I store the image
you supplied using a different tool (Microsoft Paint, of all things), the output image is
about 15 percent smaller than the one produced by Apache Imaging's TIFF writer. And because
your own original image is so much larger than the sample you posted, the reduction ratio
would probably be much larger... Perhaps large enough to account for the 50 percent difference
you cited in your post.

Fixing this Issue:

Implementing the JPEG compression option would be a lot of work, but implementing predictive
modeling might be manageable.  My feeling is that we could try fixing the predictive modeling
feature as part of this tracker item and treat the lack of a JPEG compression  issue as a
separate issue.

> TIFF image gains significant size using TiffImageWriterLossless
> ---------------------------------------------------------------
>                 Key: IMAGING-170
>                 URL:
>             Project: Commons Imaging
>          Issue Type: Bug
>          Components: Format: TIFF
>    Affects Versions: 1.0
>         Environment: System: Fedora release 21, kernel version: 3.18.7-200.fc21.x86_64,
JAVA: openjdk version "1.8.0_31", IDE: Eclipse Kepler 2, Build id: 20140224-0627
>            Reporter: Remigiusz Malessa
>            Priority: Minor
>         Attachments: kwf00346.tif
> Good afternoon, 
> I am posting an issue report as suggested by mr Benedikt Ritter. It's my first issue
report and I've just recently started using the Commons Imaging,  so please go easy on me.

> ------------------------------------------------
> Using Commons Imaging I am reading a Tiff image (will attempt to attach it to this ticket),
then I remove a tag (Focal Plane Resolution Unit) and then I save the new TiffOutputSet to
the system using TiffImageWriterLossless.
> The original image is 15MB, the new image (with the Tag removed) is 28MB.
> Here's how I do it:
> {|borderStyle=solid}
> import java.awt.image.BufferedImage;
> import;
> import;
> import;
> import;
> import java.util.HashMap;
> import java.util.List;
> import java.util.Map;
> import org.apache.camel.Exchange;
> import org.apache.commons.imaging.ImageFormats;
> import org.apache.commons.imaging.ImageReadException;
> import org.apache.commons.imaging.ImageWriteException;
> import org.apache.commons.imaging.Imaging;
> import org.apache.commons.imaging.common.ImageMetadata;
> import org.apache.commons.imaging.formats.tiff.TiffField;
> import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
> import org.apache.commons.imaging.formats.tiff.write.TiffImageWriterLossless;
> import org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory;
> import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;
> File tInputFile = new File("/home/rem/TEMP/tags.original.tif");
> File toutputFile = new File("/home/rem/TEMP/");
> final BufferedImage image = Imaging.getBufferedImage(tInputFile);
> ImageMetadata tMetadata = Imaging.getMetadata(tInputFile);
> TiffImageMetadata imageMetadata = (TiffImageMetadata) tMetadata;
> outputSet = imageMetadata.getOutputSet();
> TiffOutputDirectory exifDirectory = outputSet.getExifDirectory(); 
> exifDirectory.removeField(41488);
> ImageFormats format = ImageFormats.TIFF;
> Map<String, Object> params = new HashMap<String, Object>();
> BufferedImage image = Imaging.getBufferedImage(tInputFile);
> byte[] bytes = Imaging.writeImageToBytes(image, format, params);
> TiffImageWriterLossless writerLossLess = new TiffImageWriterLossless(bytes);
> writerLossLess.write(os, outputSet);
> {code}

This message was sent by Atlassian JIRA

View raw message