java 给图片打水印
JAVA中使用BufferedImage操作,合成图片,在一张图片上加入新的图片,文字等。以下是关键方法,供大家学习使用,省得走弯路,有任何问题希望您不吝指正,谢谢。
BufferedImage是Image的一个子类,BufferedImage生成的图片在内存里有一个图像缓冲区,利用这个缓冲区我们可以很方便的操作这个图片,通常用来做图片修改操作如大小变换、图片变灰、设置图片透明或不透明等。
package com.cby.image; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; /** * Created by cby on 2017/11/28. */ public class ImageTest { public static void main(String args[]) throws IOException { drawImageMark("D:\\images\\test.jpg","D:\\images\\scene2.jpg","D:\\images\\testMarker2.jpg"); //drawNew("作者:shine","D:\\images\\test.jpg","D:\\images\\testMarker.jpg",Position.LOWER_RIGHT,Color.green); } public static void drawMark(String text,String filename,String savepath) throws IOException{ drawNew(text,filename,savepath,null,null); } public static void drawNew(String text,String filename,String savepath,Position position) throws IOException{ drawNew(text,filename,savepath,position,null); } /*** * 在给定图片上面绘制文本水印 * @param text * @param filename * @param savepath * @param position 水印位置 * @param color * @throws IOException */ public static void drawNew(String text,String filename,String savepath,Position position,Color color) throws IOException { Color fontColor=color; if(fontColor==null){ fontColor=Color.black; } if(position==null){ } Position positionTmp=position; if(positionTmp==null){ positionTmp=Position.LOWER_RIGHT; } BufferedImage buf = ImageIO.read(new File(filename)); int w = buf.getWidth(),h = buf.getHeight(); BufferedImage newimage = new BufferedImage(w , h, BufferedImage.TYPE_INT_RGB); Graphics2D g = newimage.createGraphics(); g.drawImage(buf, 0, 0, w, h, null); // 图片中标识 start g.setColor(fontColor); //图片位置定位计算并且绘制 imageWHCountProcess(g,text,w,h,positionTmp); // draw end g.dispose(); ImageIO.write(newimage, "JPEG", new File(savepath)); } /*** * 图片位置定位计算 * @param g * @param text * @param w * @param h * @param positionTmp */ private static void imageWHCountProcess(Graphics2D g,String text,int w,int h,Position positionTmp){ //LOWER_RIGHT switch (positionTmp){ case TOP: int wT1=w-200/2+200; g.drawString(text, wT1+200,30); break; case CENTER: int wT2=(w-200)/2; int hT2=(h-30)/2; g.drawString(text, wT2+200,hT2+30); break; case BOTTOM: int wT3=(w-200)/2; g.drawString(text, wT3+200, h-30); break; case LOWER_RIGHT: g.drawString(text, w-200, h-30); break; default:break; } } /*** * 把带有水印的图标绘制在图片下方 * @param filename * @param filename2 * @param savepath * @throws IOException */ public static void drawImageMark(String filename,String filename2,String savepath) throws IOException{ BufferedImage buf = ImageIO.read(new File(filename)); BufferedImage buf2 = ImageIO.read(new File(filename2)); // int w = buf.getWidth(),h = buf.getHeight(); BufferedImage newimage = new BufferedImage(w , h, BufferedImage.TYPE_INT_RGB); Graphics2D g = newimage.createGraphics(); // draw start g.drawImage(buf, 0, 0, w, h, null); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,1f)); g.drawImage(buf2, w-buf2.getWidth(), h-buf2.getHeight(), buf2.getWidth(), buf2.getHeight(), null); g.dispose(); ImageIO.write(newimage, "JPEG", new File(savepath)); } /** 1. 定义枚举类型*/ public enum Position { // 利用构造函数传参 TOP(0),CENTER (1), BOTTOM (2), LOWER_RIGHT(3); /**定义私有变量*/ private int nCode ; /** 构造函数,枚举类型只能为私有*/ private Position( int _nCode) { this . nCode = _nCode; } @Override public String toString() { return String.valueOf (this.nCode ); } } }
1221
以下是是程序运行前后的图片效果对比
如果觉得前面进行添加水印时,速度跟不上,可以使用多线程和futuretask来帮你快速的完成图片处理。
我试过多线程处理响应速度一般也就是1秒多一点点,基本处于可以接受的状态,而且如果觉得这样还不行,
你可以考虑使用缓存文件系统,将生成的图片存储起来,下次如果发现有就不用再生成了。