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

本文介绍了一个Java实现的图片水印工具类的设计过程,包括如何向图片添加文字水印和图片水印,并分享了类代码及在开发过程中遇到的问题和解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

继续设计公共类,之前编写的生成验证码的类,在收集资料后发现,不能直接应用在网站的建设上,但是却能够满足得到验证码的要求,如果在工作时需要使用到改类,则需要根据实际的使用情况进行修改,调试。算是一个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的资料了, 下一步开始着手构造项目的基本框架,由浅入深,慢慢的调试。踏踏实实的进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值