/* * [Mask.java] * * Summary: Create shrouded email images from the command line or in your own programs. * * Copyright: (c) 2009-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.8 2009-04-04 Mask, command line version of Masker. */ package com.mindprod.masker; import com.mindprod.common18.FontFactory; import javax.imageio.ImageIO; import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.GraphicsEnvironment; import java.awt.RenderingHints; import java.awt.font.FontRenderContext; import java.awt.font.LineMetrics; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import static java.lang.System.*; /** * Create shrouded email images from the command line or in your own programs. * * @author Roedy Green, Canadian Mind Products * @version 1.8 2009-04-04 Mask, command line version of Masker. * @since 2009-04-04 */ public class Mask { /** * Best fonts to use. Takes the first one that is supported on the given system. For official names * see http://mindprod.com/fontshower.html */ private static final String[] pngFonts = new String[] { "Tiresias PCfont Z", "Tiresias PCfont", "TiresiasScreenfont", "Verdana", "Lucida Console", "Lucida Sans" };// if none of these supported, will use Dialog. /*8 foreground colour for the generated image */ private static final Color FOREGROUND = new Color( 0x777777 )/* grey */; /** * font we use to render the email text, initialised later in static init block. */ private static final Font font; // /** * HashSet of names of all supported font families */ private static final HashSet allFontFamilies; static { String[] names = ( GraphicsEnvironment.getLocalGraphicsEnvironment() ) .getAvailableFontFamilyNames(); // convert to lower case for case-insensitive lookup for ( int i = 0, n = names.length; i < n; i++ ) { names[ i ] = names[ i ].toLowerCase(); } allFontFamilies = new HashSet<>( Arrays.asList( names ) ); font = bestFont( pngFonts, Font.PLAIN, 18 ); } /** * Get the most preferred supported font from a list * * @param preferredfontNames list of font names, best one first. * @param fontStyle e.g. Font.PLAIN * @param fontSize size of font in points. * * @return best font that is supported, or a Dialog font if none are. * @noinspection SameParameterValue */ private static Font bestFont( String[] preferredfontNames, int fontStyle, int fontSize ) { // find first font in that is supported for ( String preferredfontName : preferredfontNames ) { if ( allFontFamilies.contains( preferredfontName .toLowerCase() ) ) { return FontFactory.build( preferredfontName, fontStyle, fontSize ); } } // end for return FontFactory.build( "Dialog", fontStyle, fontSize ); } /** * create a png image of a given email address without user intervention. * Use this method to create png email images in your own program. * * @param pngFile file where to store the image, must have extensions .png. The file may or may not currently exist. * @param email email address e.g. "john@yahoo.com" * * @throws IOException if cannot write the file. */ @SuppressWarnings( { "WeakerAccess" } ) public static void createMask( File pngFile, String email ) throws IOException { email = email.trim(); // FontMetrics getAscent getHeight, getDescent only approximate, have a // lot of white space. // We want more accurate LineMetrics. // We need a Graphics object in order to do line metrics. // This seems like over kill but here we go: // create a BufferedImage final BufferedImage dummybi = new BufferedImage( 200 /* dummy */, 200 /* dummy */, BufferedImage.TYPE_4BYTE_ABGR_PRE ); final Graphics2D dummyg2d = dummybi.createGraphics(); dummyg2d.setFont( font ); final FontMetrics fm = dummyg2d.getFontMetrics(); final int width = fm.stringWidth( email ); final FontRenderContext fr = dummyg2d.getFontRenderContext(); final LineMetrics lm = font.getLineMetrics( email, fr ); final int ascent = ( int ) ( lm.getAscent() + .5 ); final int height = ( int ) ( lm.getDescent() + lm.getAscent() + .5 ); // paint onto a BufferedImage final BufferedImage bufferedImage = new BufferedImage( width, height, BufferedImage.TYPE_4BYTE_ABGR_PRE ); final Graphics2D g2d = bufferedImage.createGraphics(); // redraw using our paintComponent g2d.addRenderingHints( new RenderingHints( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ) ); g2d.setFont( font ); g2d.setColor( FOREGROUND ); // background is transparent by default. // x,y is bottom left corner of tex g2d.drawString( email, 0, ascent ); // y increases going down. // write out the BufferedImage as a PNG ImageIO.write( bufferedImage, "png" /* format desired */, pngFile ); } /** * Create an png email image. * * @param args email address space name of file with .png extension * * @throws IOException if cannot write the image file. */ public static void main( String[] args ) throws IOException { if ( args.length != 2 ) { err.println( "Mask usage is mask.jar john@yahoo.com C:\\temp\\john.png" ); System.exit( 1 ); } createMask( new File( args[ 1 ] ), args[ 0 ] ); out.println( "Done" ); } }