Hi,
I am having a problem with writing EXIF Meta Data onto an existing JPEG image
using commons imaging. I am trying to set the XResolution and the YResolution
on the image. In this instance I have a photograph of a flat surface taken at
exactly 90 degrees with a calibrated rule in it. The user has the option of
specifying the length of the rule (clicking on two parts of the image) and
entering the phyiscal length. I want to then add the XResolution and
YResolution so that it can be used later to support printing the image at the
same physical size (apprciate this might not be 100% accurate). The process
originally started using scans taken via scanner where the X/YResolution would
already be on the image and useable for turning the data back into physical
space.
I am using the following code:
private static TiffImageMetadata _readImageMetaData(byte[] pImage)
{
try
{
IImageMetadata tMD = Imaging.getMetadata(pImage);
if (tMD instanceof JpegImageMetadata)
{
JpegImageMetadata tJMD = (JpegImageMetadata)tMD;
return tJMD.getExif();
}
else if (tMD instanceof TiffImageMetadata)
{
return (TiffImageMetadata)tMD;
}
}
catch (ImageReadException | IOException tEx)
{
System.out.println(tEx.getMessage());
}
return null;
}
private static org.apache.commons.imaging.formats.tiff.write.TiffOutputSet
_getExifMetadata(TiffImageMetadata oMD, String pUserID, double pPPI, int
pWidth, int pLength)
{
try
{
//the first version of this would copy the data out of the existing
TiffImageMetaData rather than creating a new TiffOutputSet
org.apache.commons.imaging.formats.tiff.write.TiffOutputSet tOutputSet = new
org.apache.commons.imaging.formats.tiff.write.TiffOutputSet();
org.apache.commons.imaging.formats.tiff.write.TiffOutputDirectory
tOutputDirectory = tOutputSet.getOrCreateRootDirectory();
tOutputDirectory.removeField(282); //XResoloution
tOutputDirectory.removeField(283); //YResoloution
tOutputDirectory.removeField(296); //ResoloutionUnit
tOutputDirectory.removeField(256); //ImageWidth
tOutputDirectory.removeField(257); //ImageLength
tOutputDirectory.add(org.apache.commons.imaging.formats.tiff.write.TiffOutputField.TIFF_TAG_XRESOLUTION,
new org.apache.commons.imaging.common.RationalNumber((int)pPPI, 1));
tOutputDirectory.add(org.apache.commons.imaging.formats.tiff.write.TiffOutputField.TIFF_TAG_YRESOLUTION,
new org.apache.commons.imaging.common.RationalNumber((int)pPPI, 1));
tOutputDirectory.add(org.apache.commons.imaging.formats.tiff.write.TiffOutputField.TIFF_TAG_RESOLUTION_UNIT,
(short)2);
tOutputDirectory.add(org.apache.commons.imaging.formats.tiff.write.TiffOutputField.EXIF_TAG_IMAGE_WIDTH,
pWidth);
tOutputDirectory.add(org.apache.commons.imaging.formats.tiff.write.TiffOutputField.EXIF_TAG_IMAGE_HEIGHT,
pLength);
tOutputDirectory.add(org.apache.commons.imaging.formats.tiff.write.TiffOutputField.TIFF_TAG_ARTIST,
pUserID);
return tOutputSet;
}
catch (ImageWriteException tEx)
{
System.out.println(tEx.getMessage());
return null;
}
}
TiffImageMetadata tMetaData = _readImageMetaData(pInstruction.mGetBytes);
//passing in a byte array[]
BufferedImage tImage = ImageIO.read(new
ByteArrayInputStream(pInstruction.mGetBytes));
//there is potentially some cropping done here depending on settings in
pInstruction, left out for space
org.apache.commons.imaging.formats.tiff.write.TiffOutputSet tOutputSet =
_getExifMetadata(tMetaData, pUserID, pInstruction.mImagePPI, tImage.getWidth(),
tImage.getHeight());
ByteArrayOutputStream tBAOS = new ByteArrayOutputStream();
//here we use ImageIO to write out the image into tBAOS (this will be the one
we have potentially cropped)
org.apache.commons.imaging.formats.jpeg.exif.ExifRewriter tRW = new
org.apache.commons.imaging.formats.jpeg.exif.ExifRewriter();
byte[] tData = tBAOS.toByteArray();
tBAOS = new ByteArrayOutputStream();
tRW.updateExifMetadataLossless(tData, tBAOS, tOutputSet);
Once this has run the image held in bytes in tBAOS will be an image with the
EXIF correctly set for the artist, but the XResolution and YResolution will be
both set to 96 DPI reegardless of any settings I put in the PPI (I hard coded a
large value and a small one, and they always come out at 96).
Am I doing something wrong or does commons imaging not support setting this
data?
Thanks
Scott
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DISCLAIMER: This email message and any attachments is for the sole
use of the intended recipient(s) and may contain confidential and
privileged information. Any unauthorised review, use, disclosure
or distribution is prohibited. If you are not the intended recipient,
please contact the sender by reply email and destroy all copies of
the original message.
The views expressed in this message may not necessarily reflect the
views of Bluestar Software Ltd.
Bluestar Software Ltd, Registered in England
Company Registration No. 03537860, VAT No. 709 2751 29
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~