diff --git a/.classpath b/.classpath index 367c9a5..673ec12 100644 --- a/.classpath +++ b/.classpath @@ -3,5 +3,7 @@ + + diff --git a/lib/metadata-extractor-2.3.1-src.jar b/lib/metadata-extractor-2.3.1-src.jar new file mode 100644 index 0000000..631f360 Binary files /dev/null and b/lib/metadata-extractor-2.3.1-src.jar differ diff --git a/lib/metadata-extractor-2.3.1.jar b/lib/metadata-extractor-2.3.1.jar new file mode 100644 index 0000000..f5f6848 Binary files /dev/null and b/lib/metadata-extractor-2.3.1.jar differ diff --git a/src/album/exif/ExifDataTest.java b/src/album/exif/ExifDataTest.java new file mode 100644 index 0000000..9a196c1 --- /dev/null +++ b/src/album/exif/ExifDataTest.java @@ -0,0 +1,224 @@ +package album.exif; + +import static org.junit.Assert.assertEquals; + +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.Iterator; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReadParam; +import javax.imageio.ImageReader; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.stream.ImageInputStream; +import javax.swing.JComponent; +import javax.swing.JFrame; + +import org.junit.Test; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.drew.imaging.jpeg.JpegMetadataReader; +import com.drew.imaging.jpeg.JpegProcessingException; +import com.drew.metadata.Directory; +import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataException; +import com.drew.metadata.Tag; +import com.drew.metadata.exif.ExifDirectory; + + +public class ExifDataTest { + + String readOrientation(String imgFile) throws IOException { + + ImageInputStream iis = ImageIO.createImageInputStream(new File(imgFile)); + Iterator readers = ImageIO.getImageReaders(iis); + ImageReader reader = readers.next(); + reader.setInput(iis); + IIOMetadata meta = reader.getImageMetadata(0); + return displayMetadata(meta); + } + + @Test + public void testOrientation() throws Exception { + + assertEquals("Top, left side (Horizontal / normal)", readOrientation2("photos/IMG_0129.JPG")); + assertEquals("Right side, top (Rotate 90 CW)", readOrientation2("photos/IMG_0139.JPG")); + + framePicture("photos/IMG_0129.JPG"); + framePicture("photos/IMG_0139.JPG"); + Thread.sleep(50000); + } + + String readOrientation2(String imgFile) throws JpegProcessingException, MetadataException { + String ret = null; + Metadata metadata = JpegMetadataReader.readMetadata(new File(imgFile)); + // iterate through metadata directories + Iterator directories = metadata.getDirectoryIterator(); + while (directories.hasNext()) { + Directory directory = (Directory) directories.next(); + // iterate through tags and print to System.out + Iterator tags = directory.getTagIterator(); + while (tags.hasNext()) { + Tag tag = (Tag) tags.next(); + // use Tag.toString() + System.out.println(tag); + if ("Orientation".equals(tag.getTagName())) { + ret = String.valueOf(tag.getDescription()); + } + } + } + return ret; + } + + public String displayMetadata(IIOMetadata metadata) { + + String ret = null; + String [] names = metadata.getMetadataFormatNames(); + for (int i = 0; i < names.length; ++i) { + System.out.println(); + System.out.println("METADATA FOR FORMAT: " + names[i]); + String r1 = displayTree(metadata.getAsTree(names[i]), 0); + if (r1 != null) { + ret = r1; + } + } + return ret; + } + + public static String displayTree(Node node, int indent) { + String ret = null; + indent(indent); + String name = node.getNodeName(); + System.out.print("<" + name); + NamedNodeMap nm = node.getAttributes(); + for (int i = 0; i < nm.getLength(); i++) { + Node an = nm.item(i); + System.out.print(" " + an.getNodeName() + "=\"" + an.getNodeValue() + "\""); + if ("ImageOrientation".equals(node.getNodeName()) && "value".equals(an.getNodeName())) { + ret = an.getNodeValue(); + } + } + if (node.hasChildNodes()) { + System.out.println(">"); + NodeList children = node.getChildNodes(); + for (int i = 0, ub = children.getLength(); i < ub; ++i) { + String r1 = displayTree(children.item(i), indent + 4); + if (r1 != null) { + ret = r1; + } + } + indent(indent); + System.out.println(""); + } else { + System.out.println("/>"); + } + return ret; + } + + static void indent(int indent) { + for (int i = 0; i < indent; ++i) + System.out.print(' '); + } + + + + + + + + + + + + + + + @Test + public void testThumbnail() throws Exception { + + assertEquals(1, getOrientationID("photos/IMG_0129.JPG")); + assertEquals(6, getOrientationID("photos/IMG_0139.JPG")); + } + +// case 1: return "Top, left side (Horizontal / normal)"; +// case 2: return "Top, right side (Mirror horizontal)"; +// case 3: return "Bottom, right side (Rotate 180)"; +// case 4: return "Bottom, left side (Mirror vertical)"; +// case 5: return "Left side, top (Mirror horizontal and rotate 270 CW)"; +// case 6: return "Right side, top (Rotate 90 CW)"; +// case 7: return "Right side, bottom (Mirror horizontal and rotate 90 CW)"; +// case 8: return "Left side, bottom (Rotate 270 CW)"; + + /** + * @param imgFile + * @return + * @throws JpegProcessingException + * @throws MetadataException + */ + int getOrientationID(String imgFile) throws JpegProcessingException, MetadataException { + Metadata metadata = JpegMetadataReader.readMetadata(new File(imgFile)); + Directory exifDirectory = metadata.getDirectory(ExifDirectory.class); + int orientation = exifDirectory.getInt(ExifDirectory.TAG_ORIENTATION); + return orientation; + } + + + + void framePicture(String imgFile) throws Exception { + + JFrame frame = new JFrame(imgFile); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + Container c = frame.getContentPane(); + c.add(new ImgComponent(imgFile)); + frame.pack(); + frame.setVisible(true); + + } + + class ImgComponent extends JComponent { + + BufferedImage img; + + public ImgComponent(String imgFile) throws IOException, JpegProcessingException, MetadataException { + Iterator readers = ImageIO.getImageReadersByFormatName("jpg"); + ImageReader reader = (ImageReader)readers.next(); + ImageInputStream iis = ImageIO.createImageInputStream(new File(imgFile)); + reader.setInput(iis, true); + ImageReadParam param = reader.getDefaultReadParam(); + param.setSourceSubsampling(8, 8, 0, 0); + img = reader.read(0, param); + + if (getOrientationID(imgFile) == 6) { + BufferedImage buf2 = new BufferedImage(img.getHeight(), img.getWidth(), img.getType()); + Graphics2D g2 = buf2.createGraphics(); + g2.translate(img.getHeight() / 2, img.getWidth() / 2); + g2.rotate(Math.PI / 2); + g2.translate(-img.getWidth() / 2, -img.getHeight() / 2); + g2.drawImage(img, 0, 0, this); + img = buf2; + } + } + + + @Override + public Dimension getPreferredSize() { + return new Dimension(img.getWidth(this), img.getHeight(this)); + } + + + @Override + public void paintComponent(Graphics g) { + + super.paintComponent(g); + g.drawImage(img, 0, 0, this); + } + } +} diff --git a/src/album/web/BitmapServlet.java b/src/album/web/BitmapServlet.java index 7bc9643..f12ecc0 100644 --- a/src/album/web/BitmapServlet.java +++ b/src/album/web/BitmapServlet.java @@ -15,7 +15,7 @@ public class BitmapServlet extends HttpServlet implements ImageObserver { - File baseDir = new File("/home/knut"); + File baseDir = new File("photos"); File cacheDir = new File("/var/album"); final static int BUF_SIZE = 1024;