现有一个业务需求,将下载的图片文件加上用户、下载时间水印。其实水印是一种比较高深的说法,说白了就是在原有图片上打印2个字串:用户和下载时间。
标准JDK提供了图片绘制函数和文字绘制函数,于是我们只要先绘制原有图像然后再绘制2个字串即可实现所谓的文字水印了,如果适当调整文字的透明度,则效果会更佳,下述为代码:
import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import javax.swing.ImageIcon; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGEncodeParam; import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class WaterPress { /** * * @param data,图像数据 * @param content,要打印的字串 * @param markContentColor,打印字串的字体颜色 * @param fontSize,字体大小,建议使用50 * @param qualNum, 透明度 * @return * @author Marcus * @date 2010-9-3 上午10:49:42 */ public byte[] createMark(byte[] data, String[] content, Color markContentColor, int fontSize, float qualNum) { byte[] pressData = null; // ImageIcon imgIcon = new ImageIcon(data); Image theImg = imgIcon.getImage(); int width = theImg.getWidth(null); int height = theImg.getHeight(null); BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = bimage.createGraphics(); g.setColor(markContentColor); g.setBackground(Color.white); g.drawImage(theImg, 0, 0, null); // g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, qualNum)); g.setFont(new Font("华文行楷", Font.ITALIC, fontSize)); // int wordYGap = fontSize+50; int wordYT = wordYGap*content.length; for(int i=0; i<content.length; i++){ String markContent = content[i]; int wordX = (width - getLength(markContent)*fontSize)/2; int wordY = (height-wordYT)/2+wordYGap*i; g.drawString(markContent, wordX, wordY); // 添加水印的文字和设置水印文字出现的内容 } g.dispose();
try { ByteArrayOutputStream os = new ByteArrayOutputStream() ; JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os); JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage); param.setQuality(0.8f, true); encoder.encode(bimage, param); pressData = os.toByteArray(); } catch (Exception e) { return null; } return pressData; }
/** * * <p>取文本长度</p> * @param text * @return * @author 11500 * @date 2010-9-3 上午10:46:58 */ private int getLength(String text) { int length = 0; for (int i = 0; i < text.length(); i++) { if (new String(text.charAt(i) + "").getBytes().length > 1) { length += 2; } else { length += 1; } } return length / 2; } } |
测试代码,为了简单起见直接用main函数了
WaterPress press = new WaterPress(); File file = new File("d://old.JPG"); FileInputStream in = new FileInputStream(file); byte fileContent[] = new byte[(int)file.length()]; in.read(fileContent); in.close(); // byte[] content = press.createMark(fileContent, new String[]{"用户:某某人","下载时间:年月日"}, Color.RED, 50, 0.3F); // File f = new File("d://new.jpg"); FileOutputStream out = new FileOutputStream(f); out.write(content); out.close(); |