imagegen: Convert identicons to SVG

to reduce memory usage
This commit is contained in:
zzz
2024-07-25 09:16:13 -04:00
parent bfb5557099
commit b39741bf52
3 changed files with 46 additions and 9 deletions

View File

@@ -153,7 +153,7 @@ public class NineBlockIdenticonRenderer2 implements IdenticonRenderer {
} }
public BufferedImage render(BigInteger code, int size) { public BufferedImage render(BigInteger code, int size) {
return renderQuilt(code.intValue(), size); return renderQuilt(null, code.intValue(), size);
} }
/** /**
@@ -172,10 +172,22 @@ public class NineBlockIdenticonRenderer2 implements IdenticonRenderer {
* @return identicon image * @return identicon image
*/ */
public BufferedImage render(int code, int size) { public BufferedImage render(int code, int size) {
return renderQuilt(code, size); return renderQuilt(null, code, size);
} }
protected BufferedImage renderQuilt(int code, int size) { /**
* @param g custom Graphics2D or null
* @since 0.9.64
*/
public BufferedImage render(Graphics2D g, int code, int size) {
return renderQuilt(g, code, size);
}
/**
* @param gg custom Graphics2D or null
* @since 0.9.64
*/
protected BufferedImage renderQuilt(Graphics2D gg, int code, int size) {
// ------------------------------------------------- // -------------------------------------------------
// PREPARE // PREPARE
// //
@@ -220,9 +232,15 @@ public class NineBlockIdenticonRenderer2 implements IdenticonRenderer {
// RENDER // RENDER
// //
BufferedImage targetImage = new BufferedImage(size, size, BufferedImage targetImage = null;
BufferedImage.TYPE_INT_RGB); Graphics2D g;
Graphics2D g = targetImage.createGraphics(); if (gg != null) {
g = gg;
} else {
targetImage = new BufferedImage(size, size,
BufferedImage.TYPE_INT_RGB);
g = targetImage.createGraphics();
}
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON); RenderingHints.VALUE_ANTIALIAS_ON);
@@ -256,7 +274,8 @@ public class NineBlockIdenticonRenderer2 implements IdenticonRenderer {
drawPatch(g, 0, blockSize2, blockSize, cornerType, cornerTurn++, drawPatch(g, 0, blockSize2, blockSize, cornerType, cornerTurn++,
cornerInvert, fillColor, strokeColor); cornerInvert, fillColor, strokeColor);
g.dispose(); if (gg == null)
g.dispose();
return targetImage; return targetImage;
} }

View File

@@ -8,6 +8,7 @@
<pathelement location="../identicon/build/identicon.jar" /> <pathelement location="../identicon/build/identicon.jar" />
<pathelement location="../zxing/build/zxing.jar" /> <pathelement location="../zxing/build/zxing.jar" />
<pathelement location="../../../build/i2p.jar" /> <pathelement location="../../../build/i2p.jar" />
<pathelement location="../../../build/jrobin.jar" />
</path> </path>
<target name="all" depends="war" /> <target name="all" depends="war" />

View File

@@ -19,6 +19,7 @@ import com.docuverse.identicon.NineBlockIdenticonRenderer2;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.data.Hash; import net.i2p.data.Hash;
import net.i2p.rrd4j.SimpleSVGGraphics2D;
import net.i2p.util.ConvertToHash; import net.i2p.util.ConvertToHash;
import net.i2p.util.Log; import net.i2p.util.Log;
@@ -67,10 +68,10 @@ public class IdenticonServlet extends HttpServlet {
private static final String PARAM_IDENTICON_SIZE_SHORT = "s"; private static final String PARAM_IDENTICON_SIZE_SHORT = "s";
private static final String PARAM_IDENTICON_CODE_SHORT = "c"; private static final String PARAM_IDENTICON_CODE_SHORT = "c";
private static final String IDENTICON_IMAGE_FORMAT = "PNG"; private static final String IDENTICON_IMAGE_FORMAT = "PNG";
private static final String IDENTICON_IMAGE_MIMETYPE = "image/png"; private static final String IDENTICON_IMAGE_MIMETYPE = "image/svg+xml";
private static final long DEFAULT_IDENTICON_EXPIRES_IN_MILLIS = 24 * 60 * 60 * 1000; private static final long DEFAULT_IDENTICON_EXPIRES_IN_MILLIS = 24 * 60 * 60 * 1000;
private int version = 1; private int version = 1;
private final IdenticonRenderer renderer = new NineBlockIdenticonRenderer2(); private final NineBlockIdenticonRenderer2 renderer = new NineBlockIdenticonRenderer2();
private IdenticonCache cache; private IdenticonCache cache;
private long identiconExpiresInMillis = DEFAULT_IDENTICON_EXPIRES_IN_MILLIS; private long identiconExpiresInMillis = DEFAULT_IDENTICON_EXPIRES_IN_MILLIS;
@@ -147,6 +148,7 @@ public class IdenticonServlet extends HttpServlet {
// retrieve image bytes from either cache or renderer // retrieve image bytes from either cache or renderer
if (cache == null if (cache == null
|| (imageBytes = cache.get(identiconETag)) == null) { || (imageBytes = cache.get(identiconETag)) == null) {
/*
ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
RenderedImage image; RenderedImage image;
try { try {
@@ -160,6 +162,20 @@ public class IdenticonServlet extends HttpServlet {
} }
ImageIO.write(image, IDENTICON_IMAGE_FORMAT, byteOut); ImageIO.write(image, IDENTICON_IMAGE_FORMAT, byteOut);
imageBytes = byteOut.toByteArray(); imageBytes = byteOut.toByteArray();
*/
SimpleSVGGraphics2D g = new SimpleSVGGraphics2D(size, size);
try {
renderer.render(g, code, size);
} catch (Throwable t) {
// java.lang.NoClassDefFoundError: Could not initialize class java.awt.GraphicsEnvironment$LocalGE
Log log = I2PAppContext.getGlobalContext().logManager().getLog(IdenticonServlet.class);
//log.logAlways(Log.WARN, "Identicon render failure: " + t);
log.error("Identicon render failure", t);
response.setStatus(403);
return;
}
String s = g.getSVG();
imageBytes = s.getBytes("UTF-8");
if (cache != null) if (cache != null)
cache.add(identiconETag, imageBytes); cache.add(identiconETag, imageBytes);
} else { } else {
@@ -178,6 +194,7 @@ public class IdenticonServlet extends HttpServlet {
// return image bytes to requester // return image bytes to requester
response.setContentType(IDENTICON_IMAGE_MIMETYPE); response.setContentType(IDENTICON_IMAGE_MIMETYPE);
response.setCharacterEncoding("UTF-8");
response.setHeader("X-Content-Type-Options", "nosniff"); response.setHeader("X-Content-Type-Options", "nosniff");
response.setHeader("Accept-Ranges", "none"); response.setHeader("Accept-Ranges", "none");
response.setContentLength(imageBytes.length); response.setContentLength(imageBytes.length);