You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Remi Malessa <re...@llgc.org.uk> on 2015/04/27 10:44:26 UTC

[imaging] Images gain size.

Hi,

I work with scanned Tiff images. Because of the type of scanner used, 
there is a tag I need to remove.
I tried to accomplish this with Commons Imaging libraries.

The problem is, the images gain significantly in size, after the operation:

15M tags.original.tif
28M tags.new.tif

Here's how I remove the Tag:

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);

TiffOutputSet outputSet = null;
OutputStream os = new FileOutputStream(toutputFile);

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>();
byte[] bytes = Imaging.writeImageToBytes(image, format, params);

TiffImageWriterLossless writerLossLess = new TiffImageWriterLossless(bytes);
writerLossLess.write(os, outputSet);


Would much appreciate if somebody could tell me if there is a method to 
trim or prevent creation of the extra data when saving the image + set, 
to a file ?


Cheers
Remi

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org


Re: [imaging] Images gain size.

Posted by Remi Malessa <re...@llgc.org.uk>.
Benedikt,

I hope this is Ok:
https://issues.apache.org/jira/browse/IMAGING-170

Cheers
Remi


On 27/04/15 13:56, Benedikt Ritter wrote:
> That would be great! Could you provide an image view our bug tracking
> system [1] and a sample implementation for reproducing the problem?
>
> Benedikt


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org


Re: [imaging] Images gain size.

Posted by Benedikt Ritter <br...@apache.org>.
2015-04-27 13:08 GMT+02:00 Remi Malessa <re...@llgc.org.uk>:

> Wow, thanks for having a look.
>
> Let me know if you need something, like a sample tif ?
>

That would be great! Could you provide an image view our bug tracking
system [1] and a sample implementation for reproducing the problem?

Benedikt

[1] http://issues.apache.org/jira/browse/IMAGING


>
> Cheers
> Remi
>
> On 27/04/15 11:53, Benedikt Ritter wrote:
>
>> I'll need some time to look into this. I'll try to put a minimal test
>> together to reproduce this. br, Benedikt
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
> For additional commands, e-mail: user-help@commons.apache.org
>
>


-- 
http://people.apache.org/~britter/
http://www.systemoutprintln.de/
http://twitter.com/BenediktRitter
http://github.com/britter

Re: [imaging] Images gain size.

Posted by Remi Malessa <re...@llgc.org.uk>.
Wow, thanks for having a look.

Let me know if you need something, like a sample tif ?

Cheers
Remi

On 27/04/15 11:53, Benedikt Ritter wrote:
> I'll need some time to look into this. I'll try to put a minimal test 
> together to reproduce this. br, Benedikt


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org


Re: [imaging] Images gain size.

Posted by Benedikt Ritter <br...@apache.org>.
Hello Remi,

2015-04-27 10:44 GMT+02:00 Remi Malessa <re...@llgc.org.uk>:

> Hi,
>
> I work with scanned Tiff images. Because of the type of scanner used,
> there is a tag I need to remove.
> I tried to accomplish this with Commons Imaging libraries.
>
> The problem is, the images gain significantly in size, after the operation:
>
> 15M tags.original.tif
> 28M tags.new.tif
>
> Here's how I remove the Tag:
>
> 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);
>
> TiffOutputSet outputSet = null;
> OutputStream os = new FileOutputStream(toutputFile);
>
> 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>();
> byte[] bytes = Imaging.writeImageToBytes(image, format, params);
>
> TiffImageWriterLossless writerLossLess = new
> TiffImageWriterLossless(bytes);
> writerLossLess.write(os, outputSet);
>
>
> Would much appreciate if somebody could tell me if there is a method to
> trim or prevent creation of the extra data when saving the image + set, to
> a file ?
>

I'll need some time to look into this. I'll try to put a minimal test
together to reproduce this.

br,
Benedikt


>
>
> Cheers
> Remi
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
> For additional commands, e-mail: user-help@commons.apache.org
>
>


-- 
http://people.apache.org/~britter/
http://www.systemoutprintln.de/
http://twitter.com/BenediktRitter
http://github.com/britter

Re: [imaging] Images gain size.

Posted by Thad Humphries <th...@gmail.com>.
Good luck. You are dealing with *far larger* images than I am, and probably
different compression. My images are all single page TIFF Gp IV, 200 to 300
dpi, Letter and Legal size, and range from 50K to 115K. This is typical for
us.

On Mon, Apr 27, 2015 at 10:25 AM, Remi Malessa <re...@llgc.org.uk> wrote:

> Thanks for the code Thad, I'll give it a whirl !
>
> Remi
>
> On 27/04/15 14:52, Thad Humphries wrote:
>
>> I recently had the requirement for a process that would read TIFF Group IV
>> images, 'stamp' them with a string, and save the images. Below is some
>> code
>> I wrote as part of playing with options. The code barely changes the size
>> of the image. In fact, most of the size difference was from adding a
>> software tag. I've copied my code below. This will run headless if you
>> need
>> it to run on a server without access to a display. Maybe it will be of
>> use.
>>
>> (NOTE: XPath does not always work on a metadata Node tree. I've been told
>> that IIOMetadata's getAsTree() does not return a true W3C Node, so XPath
>> will not work in all cases. However I've found that it does work on the
>> Group IV's that I deal with.)
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
> For additional commands, e-mail: user-help@commons.apache.org
>
>


-- 
"Hell hath no limits, nor is circumscrib'd In one self-place; but where we
are is hell, And where hell is, there must we ever be" --Christopher
Marlowe, *Doctor Faustus* (v. 121-24)

Re: [imaging] Images gain size.

Posted by Remi Malessa <re...@llgc.org.uk>.
Thanks for the code Thad, I'll give it a whirl !

Remi

On 27/04/15 14:52, Thad Humphries wrote:
> I recently had the requirement for a process that would read TIFF Group IV
> images, 'stamp' them with a string, and save the images. Below is some code
> I wrote as part of playing with options. The code barely changes the size
> of the image. In fact, most of the size difference was from adding a
> software tag. I've copied my code below. This will run headless if you need
> it to run on a server without access to a display. Maybe it will be of use.
>
> (NOTE: XPath does not always work on a metadata Node tree. I've been told
> that IIOMetadata's getAsTree() does not return a true W3C Node, so XPath
> will not work in all cases. However I've found that it does work on the
> Group IV's that I deal with.)
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
For additional commands, e-mail: user-help@commons.apache.org


Re: [imaging] Images gain size.

Posted by Thad Humphries <th...@gmail.com>.
I recently had the requirement for a process that would read TIFF Group IV
images, 'stamp' them with a string, and save the images. Below is some code
I wrote as part of playing with options. The code barely changes the size
of the image. In fact, most of the size difference was from adding a
software tag. I've copied my code below. This will run headless if you need
it to run on a server without access to a display. Maybe it will be of use.

(NOTE: XPath does not always work on a metadata Node tree. I've been told
that IIOMetadata's getAsTree() does not return a true W3C Node, so XPath
will not work in all cases. However I've found that it does work on the
Group IV's that I deal with.)


public class ImageStamper {

  public static void main(String[] args) {
    new ImageStamper(args[0]);
  }

  private final static float FONT_SIZE_IN_POINTS = 12.0f;
  private final static String FONT_FAMILY = "Times New Roman";
  private final static float OFFSET_FROM_RIGHT = 3.0f;
  private final static float OFFSET_FROM_TOP = 0.3f;

  public ImageStamper() {}

  public ImageStamper(String inFilename) {
    Path p = FileSystems.getDefault().getPath(".", inFilename);
    int width = 0;
    int height = 0;
    int xDpi = 0;
    int yDpi = 0;
    ImageReader reader = getTIFFImageReader();
    ImageWriter writer = getTIFFImageWriter();

    try {
      // Make new image.
      Path outFile =
Files.createTempFile(FileSystems.getDefault().getPath("."), "tmp", ".tif");
      ImageOutputStream ios =
ImageIO.createImageOutputStream(outFile.toFile());
      writer.setOutput(ios);
      writer.prepareWriteSequence(null);

      byte [] buffer = Files.readAllBytes(p);

      // We'll need TIFFDirectory for dpi
      ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
      ImageInputStream iis = ImageIO.createImageInputStream(bais);
      reader.setInput(iis);
      int pages = reader.getNumImages(true);

      for (int page = 0; page < pages; page++) {
        BufferedImage image = reader.read(page);
        IIOMetadata inMetadata = reader.getImageMetadata(page);
        TIFFDirectory tiffDir =
TIFFDirectory.createFromMetadata(inMetadata);

        // Get size
        TIFFField w =
tiffDir.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH);
        width = (w != null) ? w.getAsInt(0) : image.getWidth();
        TIFFField h =
tiffDir.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_LENGTH);
        height = (h!= null) ? h.getAsInt(0) : image.getHeight();

        // Get dpi
        TIFFField xrez =
tiffDir.getTIFFField(BaselineTIFFTagSet.TAG_X_RESOLUTION);
        xDpi = (xrez != null) ? xrez.getAsInt(0) : 72;
        TIFFField yrez =
tiffDir.getTIFFField(BaselineTIFFTagSet.TAG_Y_RESOLUTION);
        yDpi = (yrez != null) ? yrez.getAsInt(0) : 72;
        TIFFField rezu =
tiffDir.getTIFFField(BaselineTIFFTagSet.TAG_RESOLUTION_UNIT);
        int rezUnit = (rezu != null) ? rezu.getAsInt(0) :
BaselineTIFFTagSet.RESOLUTION_UNIT_INCH;
        if (rezUnit == BaselineTIFFTagSet.RESOLUTION_UNIT_CENTIMETER) {
          xDpi = (int)((float)xDpi/2.54);
          yDpi = (int)((float)yDpi/2.54);
        }

        Graphics2D g2 = image.createGraphics();

        // Scale the font.
        float fontRatio = xDpi/72.0f;
        int fontSize = Math.round(FONT_SIZE_IN_POINTS * fontRatio);

        // Set up the font.
        Map<TextAttribute, Object> fontAttributes = new
HashMap<TextAttribute, Object>();
        fontAttributes.put(TextAttribute.FAMILY, FONT_FAMILY);
        fontAttributes.put(TextAttribute.SIZE, fontSize);
        fontAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
        Font font = new Font("Serif", fontSize, Font.BOLD);
        font = font.deriveFont(fontAttributes);
        g2.setFont(font);
        FontMetrics fm = g2.getFontMetrics();

        // Text
        String stamp = "PLACE STAMP HERE";

        g2.setColor(java.awt.Color.black);
        g2.setPaintMode();

        // Position & print top right
        int y = Math.round(OFFSET_FROM_TOP * yDpi + fm.getMaxDescent());
        int x = width - Math.round(OFFSET_FROM_RIGHT * xDpi) -
fm.stringWidth(stamp);
        g2.drawString(stamp, x, y);

        // Position & print in other locations.

        // Set compression while writing.
        ImageWriteParam writeParam = writer.getDefaultWriteParam();
        writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        writeParam.setCompressionType("CCITT T.6");
        writeParam.setCompressionQuality(1.0f);

        // Get the initial metadata
        ImageTypeSpecifier spec =
ImageTypeSpecifier.createFromRenderedImage(image);
        IIOMetadata metadata = writer.getDefaultImageMetadata(spec,
writeParam);
        String formatName = metadata.getNativeMetadataFormatName();

        // Reset the metadata with new values.
        try {
          Node metadataNode = metadata.getAsTree(formatName);
          XPathFactory factory = XPathFactory.newInstance();
          XPath xpath = factory.newXPath();
          NodeList items = (NodeList) xpath.evaluate("//TIFFField",
metadataNode, XPathConstants.NODESET);
          for (int i = 0; i < items.getLength(); i++) {
            Node item = items.item(i);
            int tagNumber = Integer.parseInt(((Element)
item).getAttributeNode("number").getValue());
            Element e;
            switch (tagNumber) {
            case BaselineTIFFTagSet.TAG_IMAGE_WIDTH:
              e = (Element) xpath.evaluate("TIFFShorts/TIFFShort", item,
XPathConstants.NODE);
              e.getAttributeNode("value").setValue("" + width);
              break;
            case BaselineTIFFTagSet.TAG_IMAGE_LENGTH:
              e = (Element) xpath.evaluate("TIFFShorts/TIFFShort", item,
XPathConstants.NODE);
              e.getAttributeNode("value").setValue("" + height);
              break;
            case BaselineTIFFTagSet.TAG_ROWS_PER_STRIP:
              e = (Element) xpath.evaluate("TIFFShorts/TIFFShort", item,
XPathConstants.NODE);
              e.getAttributeNode("value").setValue("" + height);
              break;
            case BaselineTIFFTagSet.TAG_X_RESOLUTION:
              e = (Element) xpath.evaluate("TIFFRationals/TIFFRational",
item, XPathConstants.NODE);
              e.getAttributeNode("value").setValue("" + xDpi + "/1");
              break;
            case BaselineTIFFTagSet.TAG_Y_RESOLUTION:
              e = (Element) xpath.evaluate("TIFFRationals/TIFFRational",
item, XPathConstants.NODE);
              e.getAttributeNode("value").setValue("" + yDpi + "/1");
              break;
            case BaselineTIFFTagSet.TAG_RESOLUTION_UNIT:
              e = (Element) xpath.evaluate("TIFFShorts/TIFFShort", item,
XPathConstants.NODE);
              e.getAttributeNode("value").setValue("2");
              e.getAttributeNode("description").setValue("Inch");
              break;
            }
          }

          // Add software tag.
          IIOMetadataNode tiffFieldNode = new IIOMetadataNode("TIFFField");
          tiffFieldNode.setAttribute("name", "Software");
          tiffFieldNode.setAttribute("number", "" +
BaselineTIFFTagSet.TAG_SOFTWARE);
          IIOMetadataNode asciisNode = new IIOMetadataNode("TIFFAsciis");
          IIOMetadataNode asciiNode = new IIOMetadataNode("TIFFAscii");
          asciiNode.setAttribute("keyword", "Software");
          asciiNode.setAttribute("value", "Test of stamper positioning.");
          asciisNode.appendChild(asciiNode);
          tiffFieldNode.appendChild(asciisNode);
          Element tiffIfd = (Element) xpath.evaluate("//TIFFIFD",
metadataNode, XPathConstants.NODE);
          tiffIfd.appendChild(tiffFieldNode);

          // Set new metadata.
          metadata.setFromTree(formatName, metadataNode);
        }
        catch (XPathExpressionException e) {
          e.printStackTrace();
        }

        // Convert to an IIOImage and write.
        IIOImage iioImage = new IIOImage(image, null, metadata);
        writer.writeToSequence(iioImage, writeParam);
      }
      writer.endWriteSequence();
      iis.close();
      ios.close();
      System.out.println("TIFF image written: "+outFile.toString());
    }
    catch (IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * Return an image reader for TIFF files.
   * @return an image reader.
   */
  private ImageReader getTIFFImageReader() {
    Iterator<ImageReader> readers =
ImageIO.getImageReadersByFormatName("tiff");
    while (readers.hasNext()) {
      ImageReader reader = (ImageReader) readers.next();
      // Bypass the reader known to be buggy on the Mac.
      if
(!reader.toString().startsWith("com.sun.imageio.plugins.tiff.TIFFImageReader"))
        return reader;
    }
    return null;
  }

  /**
   * Return an image writer for TIFF files.
   * @return an image writer.
   */
  private static ImageWriter getTIFFImageWriter() {
    Iterator<ImageWriter> writers =
ImageIO.getImageWritersByFormatName("tiff");
    while (writers.hasNext()) {
      ImageWriter writer = writers.next();
      // Is there a buggy Mac type?
      return writer;
    }
    return null;
  }

}


On Mon, Apr 27, 2015 at 4:44 AM, Remi Malessa <re...@llgc.org.uk> wrote:

> Hi,
>
> I work with scanned Tiff images. Because of the type of scanner used,
> there is a tag I need to remove.
> I tried to accomplish this with Commons Imaging libraries.
>
> The problem is, the images gain significantly in size, after the operation:
>
> 15M tags.original.tif
> 28M tags.new.tif
>
> Here's how I remove the Tag:
>
> 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);
>
> TiffOutputSet outputSet = null;
> OutputStream os = new FileOutputStream(toutputFile);
>
> 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>();
> byte[] bytes = Imaging.writeImageToBytes(image, format, params);
>
> TiffImageWriterLossless writerLossLess = new
> TiffImageWriterLossless(bytes);
> writerLossLess.write(os, outputSet);
>
>
> Would much appreciate if somebody could tell me if there is a method to
> trim or prevent creation of the extra data when saving the image + set, to
> a file ?
>
>
> Cheers
> Remi
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
> For additional commands, e-mail: user-help@commons.apache.org
>
>


-- 
"Hell hath no limits, nor is circumscrib'd In one self-place; but where we
are is hell, And where hell is, there must we ever be" --Christopher
Marlowe, *Doctor Faustus* (v. 121-24)