JAVA编写的图片水印添加(文字水印、图片水印)

来源:互联网 发布:光环大数据 知乎 编辑:程序博客网 时间:2024/05/21 10:13

继续设计公共类,之前编写的生成验证码的类,在收集资料后发现,不能直接应用在网站的建设上,但是却能够满足得到验证码的要求,如果在工作时需要使用到改类,则需要根据实际的使用情况进行修改,调试。算是一个demo类型的练手吧,接下来,我编写了生成水印的工具类,在有做验证码图片的基础后, 水印生成类的编写显得更加顺利。

现贴上类代码,供参考,希望可以互相交流提高。


public class ImageChange {private String fileAddress; //需要被处理的图片地址private String addStr; //添加水印的文字private String addImageAddress; //添加图片水印的水印图片地址/*初始化方法,默认设置所有的成员属性为空*/public ImageChange(){this.fileAddress = "";this.addImageAddress = "";this.addStr = "";}/*设置需要被处理的文件的地址*/public void setFileAddress(String fileAddress) {this.fileAddress = fileAddress;}/*设置添加水印的文字*/public void setAddStr(String addStr) {this.addStr = addStr;}/*设置水印图片的地址*/public void setAddImage(String addImage) {this.addImageAddress = addImage;}/*设置所有成员属性的函数*/public void setParameter(String fileAddress,String addStr,String addImage){this.fileAddress = fileAddress;this.addStr = addStr;this.addImageAddress = addImage;}/*向图片中添加文字水印*/public void drawString(){//用fileAddress找到对应的需要添加水印的文件File oldFile = new File(this.fileAddress);//try、catch语句,用于抛出异常try {//读取出fileAddress对应的文件到一个Image变量Image image = ImageIO.read(oldFile);//取得图片的宽和高int width = image.getWidth(null);int height = image.getHeight(null);//创建一个BufferedImage变量,用于对图片的绘制操作BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//取得Graphics2D变量Graphics2D g = bi.createGraphics();//将需要添加水印的文件绘制到Graphics2D中。g.drawImage(image, 0, 0, width, height, null);//设置一个字体,最后的字号数需要根据最后的水印图片大小进行调整Font font = new Font("黑体",Font.BOLD,25);g.setFont(font);g.setColor(Color.ORANGE);//通过image的上下文,设置接下来要绘制的图形的透明度,0.0为全透明,1.0为完全不透明g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.4F));int x = 0;int y = 0;//根据需要,计算出绘制水印的坐标位置x = (width)-(25*this.addStr.length())-5;y = height-5;//绘制文字水印到g中。g.drawString(this.addStr, x, y);//使之前的绘制操作生效g.dispose();//将重新绘制得到的图片输出到原来的文件中ImageIO.write(bi, "jpg", oldFile);} catch (IOException e) {e.printStackTrace();}}/*向图片中添加图片水印*/public void drawImage(){//根据fileAddress得到需要添加水印的图片文件。File oldFile = new File(this.fileAddress);//根据addImageAddress得到水印图片File waterFile = new File(this.addImageAddress);//try,catch语句抛出异常try {//取得文件图片到Image变量中Image oldImage = ImageIO.read(oldFile);//获得原图片的宽和高int width = oldImage.getWidth(null);int height = oldImage.getHeight(null);//创建一个BufferedImage用于图片的绘制BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//取得图片上下文Graphics2D g = bi.createGraphics();//心绘制出来原本的图片g.drawImage(oldImage, 0, 0, width, height, null);//为接下来的绘制设定透明度g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5F));//获得水印图片Image waterImage = ImageIO.read(waterFile);//取得的水印图片的宽和高int waterWidth = waterImage.getWidth(null);int waterHeight = waterImage.getHeight(null);//根据需要计算出绘制的坐标int x = (width)-5-waterWidth;int y = height-(5+25)-waterHeight;//通过绘制函数,在原图片上绘制出水印g.drawImage(waterImage, x, y, waterWidth, waterHeight, null);//使之前的操作生效g.dispose();//输出到源文件的位置ImageIO.write(bi, "jpg", oldFile);} catch (IOException e) {e.printStackTrace();}}}


总结:因为是练习时编写的类代码,所以我加了大量的注释,显得有些多余,但是保证了所有人都能看懂我的思路,这也对今后的使用提供了方便。

下面是2个工具类编写时得到的经验:

1、在编写验证码类的时候,明显的觉得,计算出绘制位置是一件最麻烦的事情,字体字号都要自己设置,如果下次改进的时候,将字体字号作为参数传进来,那么计算绘制函数的公式就 不能用了,这是明显需要改进的一点。

2、我并没有把类设定为static静态的类型,原因是在掌握了问题的处理方法和理解后,再次编写显得更加简单,设定非静态类更加方便做测试时候调试,还有就是符合由浅入深的逻辑吧(强词夺理)。

3、在编写水印图片类的时候,在除了之前绘制坐标确定的问题外,发现了2点注意的地方。首先是在调用函数BufferedImage。read时, 在JDK文档中有这样的一句话,“返回一个BufferedImage,作为使用 ImageReader(它是从当前已注册 ImageReader 中自动选择的)解码所提供File 的结果。该 File 被包装在一个 ImageInputStream 中。如果没有已注册的ImageReader 声称能够读取得到的流,则返回 null。 ”起初不是很明白他的意思,在做junit测试的时候,我首先选择的水印图片是一张格式为ICO的文件,测试时报错,大体的意识是对应的注册机类中的枚举值出错。根据错误明白了这句文档翻译的意思,就是说不是所有的图片格式多可以通过read函数取得。还有一点也是图片格式的问题,GIF格式的图片是没办法绘制成水印图片的。



接着学习Hibernate的资料了, 下一步开始着手构造项目的基本框架,由浅入深,慢慢的调试。踏踏实实的进步。

0 0
原创粉丝点击