From commits-return-26102-apmail-commons-commits-archive=commons.apache.org@commons.apache.org Sat Mar 17 08:58:25 2012 Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4FF8A9128 for ; Sat, 17 Mar 2012 08:58:25 +0000 (UTC) Received: (qmail 39776 invoked by uid 500); 17 Mar 2012 08:58:25 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 39575 invoked by uid 500); 17 Mar 2012 08:58:19 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 39548 invoked by uid 99); 17 Mar 2012 08:58:19 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 17 Mar 2012 08:58:19 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 17 Mar 2012 08:58:16 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 7E03C238899C for ; Sat, 17 Mar 2012 08:57:56 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1301892 - in /commons/proper/sanselan/trunk: ./ src/main/java/org/apache/commons/sanselan/ src/main/java/org/apache/commons/sanselan/formats/bmp/ src/main/java/org/apache/commons/sanselan/formats/pcx/ src/main/java/org/apache/commons/sanse... Date: Sat, 17 Mar 2012 08:57:56 -0000 To: commits@commons.apache.org From: damjan@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120317085756.7E03C238899C@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: damjan Date: Sat Mar 17 08:57:55 2012 New Revision: 1301892 URL: http://svn.apache.org/viewvc?rev=1301892&view=rev Log: Allow writing pixel density (DPI) into images. Jira issue key: SANSELAN-67 Added: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/PixelDensity.java (with props) Modified: commons/proper/sanselan/trunk/pom.xml commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/bmp/BmpImageParser.java commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxImageParser.java commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxWriter.java commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/png/PngConstants.java commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/png/PngWriter.java commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffImageWriterBase.java Modified: commons/proper/sanselan/trunk/pom.xml URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/pom.xml?rev=1301892&r1=1301891&r2=1301892&view=diff ============================================================================== --- commons/proper/sanselan/trunk/pom.xml (original) +++ commons/proper/sanselan/trunk/pom.xml Sat Mar 17 08:57:55 2012 @@ -118,6 +118,60 @@ + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + + org.apache.maven.plugins + + + maven-antrun-plugin + + [1.6,) + + run + + + + + false + + + + + + org.apache.felix + + maven-bundle-plugin + + + [2.3.5,) + + + manifest + + + + + false + + + + + + + + + Added: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/PixelDensity.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/PixelDensity.java?rev=1301892&view=auto ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/PixelDensity.java (added) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/PixelDensity.java Sat Mar 17 08:57:55 2012 @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.sanselan; + +public class PixelDensity { + private double horizontalDensity; + private double verticalDensity; + /// One-tenth of a millimetre units. + private int unitLength; + + private PixelDensity(double horizontalDensity, double verticalDensity, int unitLength) { + this.horizontalDensity = horizontalDensity; + this.verticalDensity = verticalDensity; + this.unitLength = unitLength; + } + + public static PixelDensity createUnitless(double x, double y) { + return new PixelDensity(x, y, 0); + } + + public static PixelDensity createFromPixelsPerInch(double x, double y) { + return new PixelDensity(x, y, 254); + } + + public static PixelDensity createFromPixelsPerMetre(double x, double y) { + return new PixelDensity(x, y, 10000); + } + + public static PixelDensity createFromPixelsPerCentimetre(double x, double y) { + return new PixelDensity(x, y, 100); + } + + public boolean isUnitless() { + return unitLength == 0; + } + + public boolean isInInches() { + return unitLength == 254; + } + + public boolean isInCentimetres() { + return unitLength == 100; + } + + public boolean isInMetres() { + return unitLength == 10000; + } + + public double getRawHorizontalDensity() { + return horizontalDensity; + } + + public double getRawVerticalDensity() { + return verticalDensity; + } + + public double horizontalDensityInches() { + if (isInInches()) { + return horizontalDensity; + } else { + return horizontalDensity * 254 / unitLength; + } + } + + public double verticalDensityInches() { + if (isInInches()) { + return verticalDensity; + } else { + return verticalDensity * 254 / unitLength; + } + } + + public double horizontalDensityMetres() { + if (isInMetres()) { + return horizontalDensity; + } else { + return horizontalDensity * 10000 / unitLength; + } + } + + public double verticalDensityMetres() { + if (isInMetres()) { + return verticalDensity; + } else { + return verticalDensity * 10000 / unitLength; + } + } + + public double horizontalDensityCentimetres() { + if (isInCentimetres()) { + return horizontalDensity; + } else { + return horizontalDensity * 100 / unitLength; + } + } + + public double verticalDensityCentimetres() { + if (isInCentimetres()) { + return verticalDensity; + } else { + return verticalDensity * 100 / unitLength; + } + } +} Propchange: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/PixelDensity.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java?rev=1301892&r1=1301891&r2=1301892&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java Sat Mar 17 08:57:55 2012 @@ -118,17 +118,9 @@ public interface SanselanConstants /** * Parameter key. Used in write operations to indicate the desired - * x resolution to write into the image. + * pixel density (DPI), and/or aspect ratio. *

- * Valid values: any Integer + * Valid values: PixelDensity */ - public static final String PARAM_KEY_X_RESOLUTION = "X_RESOLUTION"; - - /** - * Parameter key. Used in write operations to indicate the desired - * y resolution to write into the image. - *

- * Valid values: any Integer - */ - public static final String PARAM_KEY_Y_RESOLUTION = "Y_RESOLUTION"; + public static final String PARAM_KEY_PIXEL_DENSITY = "PIXEL_DENSITY"; } Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/bmp/BmpImageParser.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/bmp/BmpImageParser.java?rev=1301892&r1=1301891&r2=1301892&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/bmp/BmpImageParser.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/bmp/BmpImageParser.java Sat Mar 17 08:57:55 2012 @@ -35,6 +35,7 @@ import org.apache.commons.sanselan.Image import org.apache.commons.sanselan.ImageParser; import org.apache.commons.sanselan.ImageReadException; import org.apache.commons.sanselan.ImageWriteException; +import org.apache.commons.sanselan.PixelDensity; import org.apache.commons.sanselan.common.BinaryOutputStream; import org.apache.commons.sanselan.common.IImageMetadata; import org.apache.commons.sanselan.common.ImageBuilder; @@ -772,16 +773,13 @@ public class BmpImageParser extends Imag // make copy of params; we'll clear keys as we consume them. params = (params == null) ? new HashMap() : new HashMap(params); - Integer xResolution = Integer.valueOf(0); - Integer yResolution = Integer.valueOf(0); + PixelDensity pixelDensity = null; // clear format key. if (params.containsKey(PARAM_KEY_FORMAT)) params.remove(PARAM_KEY_FORMAT); - if (params.containsKey(PARAM_KEY_X_RESOLUTION)) - xResolution = (Integer) params.remove(PARAM_KEY_X_RESOLUTION); - if (params.containsKey(PARAM_KEY_Y_RESOLUTION)) - yResolution = (Integer) params.remove(PARAM_KEY_Y_RESOLUTION); + if (params.containsKey(PARAM_KEY_PIXEL_DENSITY)) + pixelDensity = (PixelDensity) params.remove(PARAM_KEY_PIXEL_DENSITY); if (params.size() > 0) { @@ -829,8 +827,8 @@ public class BmpImageParser extends Imag bos.write4Bytes(BI_RGB); // Compression bos.write4Bytes(imagedata.length); // Bitmap Data Size - bos.write4Bytes(xResolution.intValue()); // HResolution - bos.write4Bytes(yResolution.intValue()); // VResolution + bos.write4Bytes(pixelDensity != null ? (int)Math.round(pixelDensity.horizontalDensityMetres()) : 0); // HResolution + bos.write4Bytes(pixelDensity != null ? (int)Math.round(pixelDensity.verticalDensityMetres()) : 0); // VResolution if (palette == null) bos.write4Bytes(0); // Colors else Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxImageParser.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxImageParser.java?rev=1301892&r1=1301891&r2=1301892&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxImageParser.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxImageParser.java Sat Mar 17 08:57:55 2012 @@ -112,7 +112,8 @@ public class PcxImageParser extends Imag int metricVDpi = (int) (pcxHeader.vDpi * 1000.0 / 2.54); return new ImageInfo("PCX", pcxHeader.nPlanes * pcxHeader.bitsPerPixel, new ArrayList(), ImageFormat.IMAGE_FORMAT_PCX, "ZSoft PCX Image", size.height, "image/x-pcx", 1, - metricVDpi, pcxHeader.vDpi / metricVDpi, metricHDpi, pcxHeader.hDpi / metricHDpi, + pcxHeader.vDpi, Math.round(size.getHeight() / pcxHeader.vDpi), + pcxHeader.hDpi, Math.round(size.getWidth() / pcxHeader.hDpi), size.width, false, false, !(pcxHeader.nPlanes == 3 && pcxHeader.bitsPerPixel == 8), ImageInfo.COLOR_TYPE_RGB, Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxWriter.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxWriter.java?rev=1301892&r1=1301891&r2=1301892&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxWriter.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxWriter.java Sat Mar 17 08:57:55 2012 @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.Map; import org.apache.commons.sanselan.ImageWriteException; +import org.apache.commons.sanselan.PixelDensity; import org.apache.commons.sanselan.common.BinaryOutputStream; import org.apache.commons.sanselan.palette.PaletteFactory; import org.apache.commons.sanselan.palette.SimplePalette; @@ -31,6 +32,7 @@ public class PcxWriter implements PcxCon { private int encoding; private int bitDepth = -1; + private PixelDensity pixelDensity = null; public PcxWriter(Map params) throws ImageWriteException { @@ -69,6 +71,23 @@ public class PcxWriter implements PcxCon bitDepth = ((Number)value).intValue(); } } + + if (params.containsKey(PARAM_KEY_PIXEL_DENSITY)) + { + Object value = params.remove(PARAM_KEY_PIXEL_DENSITY); + if (value != null) + { + if (!(value instanceof PixelDensity)) + throw new ImageWriteException( + "Invalid pixel density parameter"); + pixelDensity = (PixelDensity) params.remove(PARAM_KEY_PIXEL_DENSITY); + } + } + if (pixelDensity == null) + { + // DPI is mandatory, so we have to invent something + pixelDensity = PixelDensity.createFromPixelsPerInch(72, 72); + } if (params.size() > 0) { @@ -178,8 +197,8 @@ public class PcxWriter implements PcxCon bos.write2Bytes(0); // yMin bos.write2Bytes(src.getWidth() - 1); // xMax bos.write2Bytes(src.getHeight() - 1); // yMax - bos.write2Bytes(300); // hDpi - bos.write2Bytes(300); // vDpi + bos.write2Bytes((short)Math.round(pixelDensity.horizontalDensityInches())); // hDpi + bos.write2Bytes((short)Math.round(pixelDensity.verticalDensityInches())); // vDpi bos.writeByteArray(new byte[48]); // 16 color palette bos.write(0); // reserved bos.write(1); // planes @@ -220,8 +239,8 @@ public class PcxWriter implements PcxCon bos.write2Bytes(0); // yMin bos.write2Bytes(src.getWidth() - 1); // xMax bos.write2Bytes(src.getHeight() - 1); // yMax - bos.write2Bytes(300); // hDpi - bos.write2Bytes(300); // vDpi + bos.write2Bytes((short)Math.round(pixelDensity.horizontalDensityInches())); // hDpi + bos.write2Bytes((short)Math.round(pixelDensity.verticalDensityInches())); // vDpi bos.writeByteArray(new byte[48]); // 16 color palette bos.write(0); // reserved bos.write(3); // planes @@ -263,8 +282,8 @@ public class PcxWriter implements PcxCon bos.write2Bytes(0); // yMin bos.write2Bytes(src.getWidth() - 1); // xMax bos.write2Bytes(src.getHeight() - 1); // yMax - bos.write2Bytes(300); // hDpi - bos.write2Bytes(300); // vDpi + bos.write2Bytes((short)Math.round(pixelDensity.horizontalDensityInches())); // hDpi + bos.write2Bytes((short)Math.round(pixelDensity.verticalDensityInches())); // vDpi bos.writeByteArray(new byte[48]); // 16 color palette bos.write(0); // reserved bos.write(1); // planes @@ -323,8 +342,8 @@ public class PcxWriter implements PcxCon bos.write2Bytes(0); // yMin bos.write2Bytes(src.getWidth() - 1); // xMax bos.write2Bytes(src.getHeight() - 1); // yMax - bos.write2Bytes(300); // hDpi - bos.write2Bytes(300); // vDpi + bos.write2Bytes((short)Math.round(pixelDensity.horizontalDensityInches())); // hDpi + bos.write2Bytes((short)Math.round(pixelDensity.verticalDensityInches())); // vDpi bos.writeByteArray(palette16); // 16 color palette bos.write(0); // reserved bos.write(1); // planes @@ -363,8 +382,8 @@ public class PcxWriter implements PcxCon bos.write2Bytes(0); // yMin bos.write2Bytes(src.getWidth() - 1); // xMax bos.write2Bytes(src.getHeight() - 1); // yMax - bos.write2Bytes(300); // hDpi - bos.write2Bytes(300); // vDpi + bos.write2Bytes((short)Math.round(pixelDensity.horizontalDensityInches())); // hDpi + bos.write2Bytes((short)Math.round(pixelDensity.verticalDensityInches())); // vDpi bos.writeByteArray(new byte[48]); // 16 color palette bos.write(0); // reserved bos.write(1); // planes Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/png/PngConstants.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/png/PngConstants.java?rev=1301892&r1=1301891&r2=1301892&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/png/PngConstants.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/png/PngConstants.java Sat Mar 17 08:57:55 2012 @@ -47,6 +47,12 @@ public interface PngConstants extends Sa 0x58, // 0x74, // }); + public final static BinaryConstant IPHYS_CHUNK_TYPE = new BinaryConstant(new byte[] { + 'p', + 'H', + 'Y', + 's' + }); public final static int IEND = BinaryFileFunctions.charsToQuad('I', 'E', 'N', 'D'); Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/png/PngWriter.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/png/PngWriter.java?rev=1301892&r1=1301891&r2=1301892&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/png/PngWriter.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/png/PngWriter.java Sat Mar 17 08:57:55 2012 @@ -26,6 +26,7 @@ import java.util.Map; import java.util.zip.DeflaterOutputStream; import org.apache.commons.sanselan.ImageWriteException; +import org.apache.commons.sanselan.PixelDensity; import org.apache.commons.sanselan.common.ZLibUtils; import org.apache.commons.sanselan.palette.MedianCutQuantizer; import org.apache.commons.sanselan.palette.Palette; @@ -283,6 +284,22 @@ public class PngWriter implements PngCon { writeChunk(os, IDAT_CHUNK_TYPE.toByteArray(), bytes); } + + private void writeChunkPHYS(OutputStream os, int xPPU, int yPPU, byte units) + throws IOException + { + byte[] bytes = new byte[9]; + bytes[0] = (byte) (0xff & (xPPU >> 24)); + bytes[1] = (byte) (0xff & (xPPU >> 16)); + bytes[2] = (byte) (0xff & (xPPU >> 8)); + bytes[3] = (byte) (0xff & (xPPU >> 0)); + bytes[4] = (byte) (0xff & (yPPU >> 24)); + bytes[5] = (byte) (0xff & (yPPU >> 16)); + bytes[6] = (byte) (0xff & (yPPU >> 8)); + bytes[7] = (byte) (0xff & (yPPU >> 0)); + bytes[8] = (byte) units; + writeChunk(os, IPHYS_CHUNK_TYPE.toByteArray(), bytes); + } private byte getColourType(boolean hasAlpha, boolean isGrayscale) { @@ -384,6 +401,7 @@ public class PngWriter implements PngCon params.remove(PARAM_KEY_XMP_XML); if (params.containsKey(PARAM_KEY_PNG_TEXT_CHUNKS)) params.remove(PARAM_KEY_PNG_TEXT_CHUNKS); + params.remove(PARAM_KEY_PIXEL_DENSITY); if (params.size() > 0) { Object firstKey = params.keySet().iterator().next(); @@ -478,6 +496,19 @@ public class PngWriter implements PngCon writeChunkPLTE(os, palette); } + + Object pixelDensityObj = params.get(PARAM_KEY_PIXEL_DENSITY); + if (pixelDensityObj instanceof PixelDensity) + { + PixelDensity pixelDensity = (PixelDensity)pixelDensityObj; + if (pixelDensity.isUnitless()) { + writeChunkPHYS(os, (int)Math.round(pixelDensity.getRawHorizontalDensity()), + (int)Math.round(pixelDensity.getRawVerticalDensity()), (byte)0); + } else { + writeChunkPHYS(os, (int)Math.round(pixelDensity.horizontalDensityMetres()), + (int)Math.round(pixelDensity.verticalDensityMetres()), (byte)1); + } + } if (params.containsKey(PARAM_KEY_XMP_XML)) { Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffImageWriterBase.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffImageWriterBase.java?rev=1301892&r1=1301891&r2=1301892&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffImageWriterBase.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/write/TiffImageWriterBase.java Sat Mar 17 08:57:55 2012 @@ -23,11 +23,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.sanselan.ImageWriteException; +import org.apache.commons.sanselan.PixelDensity; import org.apache.commons.sanselan.common.BinaryConstants; import org.apache.commons.sanselan.common.BinaryOutputStream; import org.apache.commons.sanselan.common.PackBits; @@ -279,12 +279,10 @@ public abstract class TiffImageWriterBas params.remove(PARAM_KEY_XMP_XML); } - Integer xResolution = Integer.valueOf(72); - if (params.containsKey(PARAM_KEY_X_RESOLUTION)) - xResolution = (Integer) params.remove(PARAM_KEY_X_RESOLUTION); - Integer yResolution = Integer.valueOf(72); - if (params.containsKey(PARAM_KEY_Y_RESOLUTION)) - yResolution = (Integer) params.remove(PARAM_KEY_Y_RESOLUTION); + PixelDensity pixelDensity = (PixelDensity) params.remove(PARAM_KEY_PIXEL_DENSITY); + if (pixelDensity == null) { + pixelDensity = PixelDensity.createFromPixelsPerInch(72, 72); + } int width = src.getWidth(); int height = src.getHeight(); @@ -445,11 +443,25 @@ public abstract class TiffImageWriterBas // directory.add(field); // } directory.add(TiffTagConstants.TIFF_TAG_ROWS_PER_STRIP, rowsPerStrip); - directory.add(TiffTagConstants.TIFF_TAG_RESOLUTION_UNIT, (short)2); // inches - directory.add(TiffTagConstants.TIFF_TAG_XRESOLUTION, - RationalNumberUtilities.getRationalNumber(xResolution.doubleValue())); - directory.add(TiffTagConstants.TIFF_TAG_YRESOLUTION, - RationalNumberUtilities.getRationalNumber(yResolution.doubleValue())); + if (pixelDensity.isUnitless()) { + directory.add(TiffTagConstants.TIFF_TAG_RESOLUTION_UNIT, (short)0); + directory.add(TiffTagConstants.TIFF_TAG_XRESOLUTION, + RationalNumberUtilities.getRationalNumber(pixelDensity.getRawHorizontalDensity())); + directory.add(TiffTagConstants.TIFF_TAG_YRESOLUTION, + RationalNumberUtilities.getRationalNumber(pixelDensity.getRawVerticalDensity())); + } else if (pixelDensity.isInInches()) { + directory.add(TiffTagConstants.TIFF_TAG_RESOLUTION_UNIT, (short)2); + directory.add(TiffTagConstants.TIFF_TAG_XRESOLUTION, + RationalNumberUtilities.getRationalNumber(pixelDensity.horizontalDensityInches())); + directory.add(TiffTagConstants.TIFF_TAG_YRESOLUTION, + RationalNumberUtilities.getRationalNumber(pixelDensity.verticalDensityInches())); + } else { + directory.add(TiffTagConstants.TIFF_TAG_RESOLUTION_UNIT, (short)1); + directory.add(TiffTagConstants.TIFF_TAG_XRESOLUTION, + RationalNumberUtilities.getRationalNumber(pixelDensity.horizontalDensityCentimetres())); + directory.add(TiffTagConstants.TIFF_TAG_YRESOLUTION, + RationalNumberUtilities.getRationalNumber(pixelDensity.verticalDensityCentimetres())); + } if (t4Options != 0) { directory.add(TiffTagConstants.TIFF_TAG_T4_OPTIONS, t4Options); }