Monday, October 30, 2006

Add time stamp to picture using Java

public static void addDate(File inputFile) throws Exception {
String inputFilename = inputFile.getPath();
System.out.println("Starting with '" + inputFilename + "'");
BufferedImage input = ImageIO.read(inputFile);
Graphics2D graphics = (Graphics2D) input.createGraphics();
Date lastModified = new Date(inputFile.lastModified());
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String dateStamp = sdf.format(lastModified);
int fontSize = (int) (0.4 * input.getHeight() / 10.0);
Font font = new Font("Arial", Font.BOLD, fontSize);
graphics.setFont(font);
int height = graphics.getFontMetrics().getHeight();
int width = graphics.getFontMetrics().stringWidth(dateStamp);

BufferedImage dateImage = new BufferedImage(2 * fontSize + width, 2
* fontSize + height, BufferedImage.TYPE_INT_ARGB);
Graphics2D dateGraphics = (Graphics2D) dateImage.getGraphics().create();
dateGraphics.setColor(new Color(0, 0, 0, 0));
dateGraphics.setComposite(AlphaComposite.Src);
dateGraphics.fillRect(0, 0, width, height);

dateGraphics.setComposite(AlphaComposite.SrcOver);
dateGraphics.setFont(font);
dateGraphics.setColor(Color.black);
dateGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
GlyphVector gv = font.createGlyphVector(dateGraphics
.getFontRenderContext(), dateStamp);
// dateGraphics.drawString(dateStamp, fontSize, fontSize);
dateGraphics.translate(fontSize, 2 * fontSize);
for (int i = 0; i < gv.getNumGlyphs(); i++) {
Shape glyph = gv.getGlyphOutline(i);
dateGraphics.setStroke(new BasicStroke(fontSize / 10));
dateGraphics.draw(glyph);
}
float[] kernel = new float[25];
for (int i = 0; i < kernel.length; i++)
kernel[i] = 1.0f / kernel.length;
ConvolveOp cOp = new ConvolveOp(new Kernel(5, 5, kernel));
BufferedImage blurred = cOp.filter(dateImage, null);
dateGraphics.dispose();

int iWidth = input.getWidth();
int iHeight = input.getHeight();
int cHeight = iWidth * 2 / 3;
int dHeight = (iHeight - cHeight) / 2;

int y = (iHeight - dHeight) - blurred.getHeight();
int x = iWidth - blurred.getWidth();

graphics.drawImage(blurred, x - fontSize, y - 2 * fontSize, null);
graphics.setFont(font);
graphics.setColor(Color.white);
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
graphics.drawString(dateStamp, x, y);
graphics.dispose();

int lastDotIndex = inputFilename.lastIndexOf('.');
String outputFilename = inputFilename.substring(0, lastDotIndex)
+ ".new" + inputFilename.substring(lastDotIndex);
FileOutputStream out = new FileOutputStream(outputFilename);
/* encodes image as a JPEG data stream */
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(input);
param.setQuality(0.9f, true);
encoder.setJPEGEncodeParam(param);
encoder.encode(input);
System.out.println("Ending with '" + inputFilename + "'");
}

Of course, it's not a pinnacle of Java2D programming, nor was it intended to. Since i don't have any imaging-related java.net project, i'm not intending to polish it to perfection. It even uses classes in the com.sun.image.codec.jpeg package. Hereby it is released to the public domain - feel free to use, reuse and abuse it in any way - but don't come back if your nuclear reactor stops functioning because of this :)

The result is quite OK:

No comments: