From 68c297603afc6f0abe8925fedd00a6705d61fa38 Mon Sep 17 00:00:00 2001 From: knut Date: Sun, 30 Nov 2008 05:40:02 +0000 Subject: [PATCH] Added prev/next and etag for caching of images --- photos/irony.jpg | Bin 0 -> 23192 bytes src/org/forkalsrud/album/exif/Entry.java | 24 +++++++ src/org/forkalsrud/album/exif/EntryDao.java | 60 +++++++++++++++++- .../forkalsrud/album/web/AlbumServlet.java | 25 +++++--- webapp/WEB-INF/velocity/photo.vm | 9 +++ 5 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 photos/irony.jpg diff --git a/photos/irony.jpg b/photos/irony.jpg new file mode 100644 index 0000000000000000000000000000000000000000..48ffcddae064230d58540bfad1237d110068149c GIT binary patch literal 23192 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

&~*TvIA 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

)6LheE~rx8WTSe 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 Sp8o*Aboc!y;y=IRfB)I{Yt4QD literal 0 HcmV?d00001 diff --git a/src/org/forkalsrud/album/exif/Entry.java b/src/org/forkalsrud/album/exif/Entry.java index 4b774ae..e1a2874 100644 --- a/src/org/forkalsrud/album/exif/Entry.java +++ b/src/org/forkalsrud/album/exif/Entry.java @@ -20,6 +20,9 @@ public class Entry { String caption; Date date; int orientation; + Entry next; + Entry prev; + String etag; /** @@ -108,4 +111,25 @@ public class Entry { public void setOrientation(int orientation) { this.orientation = orientation; } + + public Entry prev() { + return prev; + } + public Entry next() { + return next; + } + + + + public String getEtag() { + return etag; + } + + + + public void setEtag(String etag) { + this.etag = etag; + } + + } diff --git a/src/org/forkalsrud/album/exif/EntryDao.java b/src/org/forkalsrud/album/exif/EntryDao.java index a02e3b8..393728f 100644 --- a/src/org/forkalsrud/album/exif/EntryDao.java +++ b/src/org/forkalsrud/album/exif/EntryDao.java @@ -5,6 +5,7 @@ package org.forkalsrud.album.exif; +import java.awt.image.BufferedImage; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; @@ -24,6 +25,11 @@ import java.util.Iterator; import java.util.List; import java.util.Properties; +import javax.imageio.ImageIO; +import javax.imageio.ImageReadParam; +import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; + import com.drew.imaging.jpeg.JpegMetadataReader; import com.drew.imaging.jpeg.JpegProcessingException; import com.drew.metadata.Directory; @@ -43,13 +49,18 @@ public class EntryDao { final static String CACHE_FILE = "cache.properties"; final static String OVERRIDE_FILE = "album.properties"; + boolean isCurrent(File directory) { + + return directory.lastModified() <= new File(directory, CACHE_FILE).lastModified(); + } + public List read(File directory) throws FileNotFoundException, IOException, JpegProcessingException, MetadataException, ParseException { List entries = new ArrayList(); Properties cachedProps = new Properties(); File cache = new File(directory, CACHE_FILE); - if (cache.exists() && cache.isFile() && cache.canRead()) { + if (cache.exists() && cache.isFile() && cache.canRead() && isCurrent(directory)) { cachedProps.load(new FileInputStream(cache)); } else { generateEntries(directory, cachedProps); @@ -80,9 +91,25 @@ public class EntryDao { } } }); + fillLinkedList(entries); return entries; } + void fillLinkedList(List entries) { + + Entry prev = null; + for (Entry e : entries) { + e.prev = prev; + if (prev != null) { + prev.next = e; + } + prev = e; + } + if (prev != null) { + prev.next = null; + } + } + private void populate(Properties cachedProps, List entries) throws ParseException { @@ -100,6 +127,7 @@ public class EntryDao { entry.setSize(new Dimension(cachedProps.getProperty("file." + name + ".dimensions"))); entry.setCaption(cachedProps.getProperty("file." + name + ".caption")); entry.setOrientation(Integer.parseInt(cachedProps.getProperty("file." + name + ".orientation"))); + entry.setEtag(cachedProps.getProperty("file." + name + ".etag")); entries.add(entry); } } @@ -137,6 +165,7 @@ public class EntryDao { String base = "file." + name + "."; boolean hasDate = false; boolean hasOrientation = false; + boolean hasDim = false; Metadata metadata = JpegMetadataReader.readMetadata(f); Directory exifDirectory = metadata.getDirectory(ExifDirectory.class); @@ -150,6 +179,7 @@ public class EntryDao { int width = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_WIDTH); int height = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT); cachedProps.setProperty(base + "dimensions", new Dimension(width, height).toString()); + hasDim = true; } if (exifDirectory.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) { Date captureDate = exifDirectory.getDate(ExifDirectory.TAG_DATETIME_ORIGINAL); @@ -166,13 +196,22 @@ public class EntryDao { int width = jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_WIDTH); int height = jpegDirectory.getInt(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT); cachedProps.setProperty(base + "dimensions", new Dimension(width, height).toString()); + hasDim = true; } + cachedProps.setProperty(base + "etag", Integer.toHexString(name.hashCode() + Long.valueOf(f.lastModified()).hashCode())); if (!hasDate) { cachedProps.setProperty(base + "captureDate", sdf.format(new Date(f.lastModified()))); } if (!hasOrientation) { cachedProps.setProperty(base + "orientation", "1"); } + if (!hasDim) { + Dimension dim = decodeImageForDimensions(f); + if (dim != null) { + cachedProps.setProperty(base + "dimensions", dim.toString()); + hasDim = true; + } + } } File dst = new File(directory, CACHE_FILE); if (directory.canWrite()) { @@ -180,5 +219,24 @@ public class EntryDao { } } + Dimension decodeImageForDimensions(File file) throws IOException { + + String suffix = null; + String name = file.getName(); + if (name.indexOf('.') > 0) { + suffix = name.substring(name.lastIndexOf('.') + 1); + } + Iterator readers = ImageIO.getImageReadersBySuffix(suffix); + if (!readers.hasNext()) { + return null; + } + ImageReader reader = readers.next(); + ImageInputStream iis = ImageIO.createImageInputStream(file); + reader.setInput(iis, true); + ImageReadParam param = reader.getDefaultReadParam(); + BufferedImage img = reader.read(0, param); + return new Dimension(img.getWidth(), img.getHeight()); + } + } diff --git a/src/org/forkalsrud/album/web/AlbumServlet.java b/src/org/forkalsrud/album/web/AlbumServlet.java index a6882a0..f4f9bd3 100644 --- a/src/org/forkalsrud/album/web/AlbumServlet.java +++ b/src/org/forkalsrud/album/web/AlbumServlet.java @@ -94,6 +94,8 @@ public class AlbumServlet try { Entry e = dao.readFile(file); req.setAttribute("entry", e); + req.setAttribute("prev", e.prev()); + req.setAttribute("next", e.next()); RequestDispatcher rd = req.getRequestDispatcher("/WEB-INF/velocity/photo.vm"); rd.forward(req, res); } catch (Exception e) { @@ -104,17 +106,22 @@ public class AlbumServlet } } + boolean etagMatches(HttpServletRequest req, HttpServletResponse res, Entry entry, String size) { + String reqEtag = req.getHeader("If-None-Match"); + String fileEtag = entry.getEtag() + "-" + size; + if (reqEtag != null) { + return reqEtag.equals(fileEtag); + } + res.setHeader("ETag", fileEtag); + return false; + } void scaleImage(HttpServletRequest req, HttpServletResponse res, File file, String size) throws IOException, JpegProcessingException, MetadataException, ParseException { - List entries = dao.read(file.getParentFile()); - Entry entry = null; - String myName = file.getName(); - for (Entry e : entries) { - if (myName.equals(e.getName())) { - entry = e; - break; - } + Entry entry = dao.readFile(file); + if (etagMatches(req, res, entry, size)) { + res.setStatus(HttpServletResponse.SC_NOT_MODIFIED); + return; } Dimension orig = entry.getSize(); Dimension outd; @@ -134,7 +141,7 @@ public class AlbumServlet ImageInputStream iis = ImageIO.createImageInputStream(file); reader.setInput(iis, true); ImageReadParam param = reader.getDefaultReadParam(); - if (true /* subsampling */) { + if (false /* subsampling */) { double subSampleScale = (double)outd.getWidth() / orig.getWidth(); int subSampling = (int)Math.floor(0.25d/subSampleScale); if (subSampling > 1) { diff --git a/webapp/WEB-INF/velocity/photo.vm b/webapp/WEB-INF/velocity/photo.vm index fc2dd9f..bace66a 100644 --- a/webapp/WEB-INF/velocity/photo.vm +++ b/webapp/WEB-INF/velocity/photo.vm @@ -34,6 +34,15 @@ +

+#if($prev) + <-- +#end +#if($next) + --> +#end +
+ #set($thmb = 480) #set($dim = $entry.size.scaled($thmb))