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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reply via email to