From 55168193545d0340b56b5d2923037c1e59b68ea6 Mon Sep 17 00:00:00 2001 From: Michael Peter Christen Date: Fri, 19 Dec 2014 17:41:38 +0100 Subject: [PATCH] preventing the use of no-cache and expires in case that images are generated dynamically which will stay static in the future. This applies mainly to the search result favicon in front of search hits. These icons will now be generated once, but then caches in the browser. There is also a YaCy-internal cache for these icons which had prevented the re-generation of the icons in YaCy, but this cache is now superfluous since the browser should not call the servlet ViewImage again. --- htroot/api/snapshot.java | 3 +- htroot/osm.java | 5 +- htroot/yacysearchitem.html | 4 +- htroot/yacysearchitem.java | 2 +- .../net/yacy/peers/graphics/EncodedImage.java | 73 ++++++++++++++++++- 5 files changed, 79 insertions(+), 8 deletions(-) diff --git a/htroot/api/snapshot.java b/htroot/api/snapshot.java index 221296c30..3c5d84737 100644 --- a/htroot/api/snapshot.java +++ b/htroot/api/snapshot.java @@ -49,6 +49,7 @@ import net.yacy.crawler.data.Transactions; import net.yacy.crawler.data.Snapshots.Revisions; import net.yacy.document.ImageParser; import net.yacy.kelondro.util.FileUtils; +import net.yacy.peers.graphics.EncodedImage; import net.yacy.search.Switchboard; import net.yacy.server.serverObjects; import net.yacy.server.serverSwitch; @@ -306,7 +307,7 @@ public class snapshot { final MediaTracker mediaTracker = new MediaTracker(new Container()); mediaTracker.addImage(scaled, 0); try {mediaTracker.waitForID(0);} catch (final InterruptedException e) {} - return scaled; + return new EncodedImage(scaled, ext, true); } catch (IOException e) { ConcurrentLog.logException(e); return null; diff --git a/htroot/osm.java b/htroot/osm.java index 2624d72be..d7d35b060 100644 --- a/htroot/osm.java +++ b/htroot/osm.java @@ -19,6 +19,7 @@ */ import net.yacy.cora.protocol.RequestHeader; +import net.yacy.peers.graphics.EncodedImage; import net.yacy.peers.graphics.OSMTile; import net.yacy.server.serverObjects; import net.yacy.server.serverSwitch; @@ -28,7 +29,7 @@ import net.yacy.visualization.RasterPlotter.DrawMode; public class osm { - public static RasterPlotter respond(@SuppressWarnings("unused") final RequestHeader header, final serverObjects post, @SuppressWarnings("unused") final serverSwitch env) { + public static EncodedImage respond(@SuppressWarnings("unused") final RequestHeader header, final serverObjects post, @SuppressWarnings("unused") final serverSwitch env) { int zoom = 10; double lat = 50.11670d; @@ -57,7 +58,7 @@ public class osm { * The (C) symbol is not available in our font, so we use the letters (C) instead. */ PrintTool.print(map, map.getWidth() - 6, map.getHeight() - 6, 0, "(C) OPENSTREETMAP CONTRIBUTORS", 1); - return map; + return new EncodedImage(map, header.get("EXT", null), true); } } \ No newline at end of file diff --git a/htroot/yacysearchitem.html b/htroot/yacysearchitem.html index 5d2d1d80e..4e6a9a027 100644 --- a/htroot/yacysearchitem.html +++ b/htroot/yacysearchitem.html @@ -1,7 +1,7 @@ #(content)#::

- + #[title]#

#(heuristic)#:: @@ -39,7 +39,7 @@ :: #(item)#::
- + #[name]# diff --git a/htroot/yacysearchitem.java b/htroot/yacysearchitem.java index 9965e9e1e..b4336675b 100644 --- a/htroot/yacysearchitem.java +++ b/htroot/yacysearchitem.java @@ -303,7 +303,7 @@ public class yacysearchitem { final String license = URLLicense.aquireLicense(image.imageUrl); // this is just the license key to get the image forwarded through the YaCy thumbnail viewer, not an actual lawful license //sb.loader.loadIfNotExistBackground(image.imageUrl, 1024 * 1024 * 10, null, ClientIdentification.yacyIntranetCrawlerAgent); - prop.putHTML("content_item_hrefCache", "/ViewImage.png?maxwidth=128&maxheight=128&quadratic=&url=" + imageUrlstring); + prop.putHTML("content_item_hrefCache", "/ViewImage.png?maxwidth=128&maxheight=128&isStatic=true&quadratic=&url=" + imageUrlstring); prop.putHTML("content_item_href", imageUrlstring); prop.putHTML("content_item_target", target); prop.put("content_item_code", license); diff --git a/source/net/yacy/peers/graphics/EncodedImage.java b/source/net/yacy/peers/graphics/EncodedImage.java index d4ca97528..a2bca1929 100644 --- a/source/net/yacy/peers/graphics/EncodedImage.java +++ b/source/net/yacy/peers/graphics/EncodedImage.java @@ -20,6 +20,8 @@ package net.yacy.peers.graphics; +import java.awt.Image; +import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -30,13 +32,63 @@ import net.yacy.visualization.RasterPlotter; public class EncodedImage { private ByteBuffer image; private String extension; + private boolean isStatic; - public EncodedImage(final RasterPlotter sourceImage, final String targetExt) { + /** + * set an encoded image; prefer this over methods with Image-source objects because png generation is faster when done from RasterPlotter sources + * @param sourceImage the image + * @param targetExt the target extension of the image when converted into a file + * @param isStatic shall be true if the image will never change, false if not + */ + public EncodedImage(final RasterPlotter sourceImage, final String targetExt, final boolean isStatic) { this.image = "png".equals(targetExt) ? sourceImage.exportPng() : RasterPlotter.exportImage(sourceImage.getImage(), targetExt); this.extension = targetExt; + this.isStatic = isStatic; } - public EncodedImage(final AnimationGIF sourceImage) { + /** + * set an encoded image from a buffered image + * @param sourceImage the image + * @param targetExt the target extension of the image when converted into a file + * @param isStatic shall be true if the image will never change, false if not + */ + public EncodedImage(final BufferedImage bi, final String targetExt, final boolean isStatic) { + this.extension = targetExt; + this.image = RasterPlotter.exportImage(bi, targetExt); + this.isStatic = isStatic; + + } + + /** + * set an encoded image from a buffered image + * @param sourceImage the image + * @param targetExt the target extension of the image when converted into a file + * @param isStatic shall be true if the image will never change, false if not + */ + public EncodedImage(final Image i, final String targetExt, final boolean isStatic) { + this.extension = targetExt; + this.isStatic = isStatic; + + // generate an byte array from the generated image + int width = i.getWidth(null); + if (width < 0) { + width = 96; // bad hack + } + int height = i.getHeight(null); + if (height < 0) { + height = 96; // bad hack + } + final BufferedImage sourceImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + sourceImage.createGraphics().drawImage(i, 0, 0, width, height, null); + this.image = RasterPlotter.exportImage(sourceImage, targetExt); + } + + /** + * set an encoded image from an animated GIF. The target extension will be "gif" + * @param sourceImage the image + * @param isStatic shall be true if the image will never change, false if not + */ + public EncodedImage(final AnimationGIF sourceImage, final boolean isStatic) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { bos.write(sourceImage.get()); @@ -45,13 +97,30 @@ public class EncodedImage { } this.image = new ByteBuffer(bos.toByteArray()); this.extension = "gif"; + this.isStatic = isStatic; } + /** + * get the encoded image + * @return the bytes of the image encoded into the target extension format + */ public ByteBuffer getImage() { return this.image; } + /** + * get the extension of the image + * @return the target extension of the encoded image + */ public String getExtension() { return this.extension; } + + /** + * get information if the information changes in the future or not if it does not change, it is static + * @return true if the image will never change, false if not + */ + public boolean isStatic() { + return this.isStatic; + } }