1   /**
2    *    Copyright 2009 Webster Smalley
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  package com.webstersmalley.watermarker;
18  
19  import java.awt.AlphaComposite;
20  import java.awt.Color;
21  import java.awt.Font;
22  import java.awt.FontMetrics;
23  import java.awt.Graphics2D;
24  import java.awt.geom.Rectangle2D;
25  import java.awt.image.BufferedImage;
26  import java.io.File;
27  import java.io.FileInputStream;
28  import java.io.FileNotFoundException;
29  import java.io.FileOutputStream;
30  import java.io.IOException;
31  import java.io.OutputStream;
32  import java.util.Properties;
33  
34  import javax.swing.UIManager;
35  import javax.swing.UnsupportedLookAndFeelException;
36  
37  import com.sun.image.codec.jpeg.JPEGCodec;
38  import com.sun.image.codec.jpeg.JPEGImageDecoder;
39  import com.sun.image.codec.jpeg.JPEGImageEncoder;
40  
41  /**
42   * @author Matthew Smalley
43   * 
44   */
45  public class WaterMarker {
46  	
47  	static {
48  		try {
49  			UIManager.setLookAndFeel(
50  			        UIManager.getSystemLookAndFeelClassName());
51  		} catch (ClassNotFoundException e) {
52  			e.printStackTrace();
53  		} catch (InstantiationException e) {
54  			e.printStackTrace();
55  		} catch (IllegalAccessException e) {
56  			e.printStackTrace();
57  		} catch (UnsupportedLookAndFeelException e) {
58  			e.printStackTrace();
59  		}
60  
61  	}
62  	
63  	private ProgressBar pb = new ProgressBar();
64  
65  	// Default Configuration
66  	private String watermarkText = "Copyright (c) 2009 Webster-Smalley"; // Tahoma - 933x64 @ size 50.
67  	private Color textForegroundColour = Color.BLUE;
68  	private Color textBackgroundColour = Color.BLACK;
69  	private int fontScaling = 3;
70  	private String fontName = "Tahoma";
71  	private float fontAlpha = 0.2f;
72  	
73  	
74  	
75  	private BufferedImage loadImage(String filename) {
76  		// Create BufferedImage
77  		BufferedImage bi = null;
78  		try {
79  			// load file from disk using Sun's JPEGIMageDecoder
80  			FileInputStream fis = new FileInputStream(filename);
81  			JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(fis);
82  			bi = decoder.decodeAsBufferedImage();
83  			fis.close();
84  		} catch (Exception e) {
85  			throw new RuntimeException("Error loading image", e);
86  		}
87  		return bi;
88  	}
89  
90  	public void addWaterMarkToFolder(String inputFoldername, String outputFoldername, boolean recurse) throws IOException {
91  		File folder = new File(inputFoldername);
92  		File[] children = folder.listFiles();
93  		
94  		pb.show();
95  		
96  		pb.incrementJobCount(children.length);
97  		
98  		for (File child: children) {
99  			pb.setCurrentJobName(child.getAbsolutePath());
100 
101 			if (child.isDirectory() && recurse) {
102 				addWaterMarkToFolder(child.getAbsolutePath(), outputFoldername + File.separator + child.getName(), true);
103 			} else if (child.getName().toLowerCase().endsWith(".jpg")) {
104 				addWaterMark(child.getAbsolutePath(), outputFoldername + File.separator + child.getName());
105 			}
106 			pb.postCompletion();
107 		}
108 	}
109 	
110 	public void addWaterMark(String inputFilename, String outputFilename) throws IOException {
111 		BufferedImage bi = loadImage(inputFilename);
112 		
113 		int imageWidth = bi.getWidth();
114 		int imageHeight = bi.getHeight();
115 		
116 		int fontSize = (imageWidth / 90) * fontScaling;
117 		if ((imageHeight / 48) * fontScaling < fontSize) {
118 			fontSize = (imageHeight / 48) * fontScaling;
119 		}
120 		
121 		Font fnt = new Font(fontName, Font.BOLD, fontSize);
122 
123 		Graphics2D g2d = (Graphics2D) bi.createGraphics();
124 
125 		FontMetrics fm = g2d.getFontMetrics(fnt);
126 		Rectangle2D stringBound = fm.getStringBounds(watermarkText, g2d);
127 		int textHeight = (int)(stringBound.getHeight()); 
128 		int textWidth  = (int)(stringBound.getWidth());
129 		int x = (imageWidth-textWidth)/2;
130 		int y = (imageHeight-textHeight)/3;
131 		
132 		g2d.setFont(fnt);
133 		g2d.setColor(textForegroundColour);
134 		g2d.setBackground(textBackgroundColour);
135 		g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, fontAlpha));
136 		g2d.drawString(watermarkText, x, y);
137 		g2d.dispose();
138 
139 		File outputfolder = new File(outputFilename).getParentFile();
140 		if (!outputfolder.exists()) {
141 			if (!outputfolder.mkdirs()) {
142 				throw new RuntimeException ("Error creating folder: " + outputfolder.getAbsolutePath());
143 			}
144 		}
145 		OutputStream os = new FileOutputStream(outputFilename);
146 		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
147 		encoder.encode(bi);
148 		os.close();
149 
150 	}
151 	
152 	public void loadProperties(String filename) throws FileNotFoundException, IOException {
153 		Properties properties = new Properties();
154 		properties.load(new FileInputStream(filename));
155 		
156 		
157 		watermarkText = properties.getProperty("watermark.text");
158 		textForegroundColour = Color.decode(properties.getProperty("watermark.colour"));
159 		textBackgroundColour = Color.decode(properties.getProperty("watermark.background"));
160 		fontScaling = Integer.parseInt(properties.getProperty("watermark.size"));
161 		fontName = properties.getProperty("watermark.font");
162 		fontAlpha = Float.parseFloat(properties.getProperty("watermark.alpha"));
163 	}
164 	
165 	public static void main(String[] args) throws Exception {
166 		if (args.length != 2) {
167 			System.out.println("Usage: watermarker inputfile/folder outputfolder");
168 			System.exit(1);
169 		}
170 
171 		WaterMarker wm = new WaterMarker();
172 
173 		if (new File("watermarker.properties").exists()) {
174 			wm.loadProperties("watermarker.properties");
175 		}
176 		
177 		File f = new File(args[0]);
178 		if (f.isDirectory()) {
179 			wm.addWaterMarkToFolder(args[0], args[1], true);
180 		} else {
181 			wm.addWaterMark(args[0], args[1]);
182 		}
183 		
184 		System.exit(0);
185 	}
186 
187 }