[
https://issues.apache.org/jira/browse/IMAGING-170?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14768929#comment-14768929
]
Gary Lucas commented on IMAGING-170:
------------------------------------
Thanks.
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 it.
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: https://issues.apache.org/jira/browse/IMAGING-170
> 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:
> {code:title=RemoveTag.java|borderStyle=solid}
> import java.awt.image.BufferedImage;
> import java.io.File;
> import java.io.FileOutputStream;
> import java.io.IOException;
> import java.io.OutputStream;
> 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/tags.new.tif");
> 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
(v6.3.4#6332)