如何使用JAVA实现数字水印
数字水印有可见不可见之分,可见的比如课件上印有学校校徽,微博发图片会水印上上传者的信息及微博logo等。
用java实现可见的数字水印,草人主要是用到了java.awt包中的alphacomposite类,当然在实现之前先介绍一下alphacomposite类:
alphacomposite类是关于两个目标重叠的混合处理类,此类实现的特定规则是 t. porter 和 t. duff 合著的 “compositing digital images”, siggraph 84, 253-259 中描述的 12 条基本规则集。该类提供的一个getinstance的方法,其中的两个参数为rule和alpha,第二个参数将由调用者设置一个alpha值,即是透明度的设置,而第一个参数则是混合方式。此类扩展了 porter 和 duff 定义的方程,包含一个额外的因子。alphacomposite 类的实例可以包含一个 alpha 值,在将该值用于混合方程之前,可以用它来修改不透明度和每个源像素的覆盖率。
porter和 duff 的论文在混合方程的描述中使用了以下因子:
以规则src_over为例,使用这些因子,porter 和 duff 定义了 12 种选择混合因子 fs 和 fd 的方法,从而产生了 12 种令人满意的可视效果。在对 12 个指定可视效果的静态字段的描述中,给出了具有确定 fs 和 fd 值的方程。src_over在目标色之上合成源色(porter-duff source over destination 规则)。指定fs = 1 和 fd = (1-as),因此:
ar = as + ad*(1-as)
cr = cs + cd*(1-as)
该类扩展后一共有24中规则,定义了9个方法,由于草人的程序中用到了方法getinstance()就对之说明一下——
•详细定义:public static alphacomposite getinstance(int rule, float alpha)
•功能:创建一个 alphacomposite 对象,它具有指定的规则和用来乘源色 alpha 值的常量 alpha 值。在将源色与目标色合成前,要将源色乘以指定的 alpha 值。
•参数:rule——合成规则,24种;alpha——将乘源色的 alpha 值的常量 alpha 值。alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字。
•抛出:illegalargumentexception - 如果 alpha 小于 0.0 或大于 1.0,或者 rule 是以下规则之一:clear、src、dst、src_over、dst_over、src_in、dst_in、src_out、dst_out、 src_atop、dst_atop 或 xor。
既然是图像处理,就先创建一个java2d对象
//用源图像填充背景
g2d.drawimage(image, 0, 0, image.getwidth(), image.getheight(), null, null);
然后为 graphics2d 上下文设置 composite后就可以将想要写入的文字或者图片写入源图片上
alphacomposite ac = alphacomposite.getinstance(alphacomposite.src_over, alpha);
//为 graphics2d 上下文设置 composite。 composite 用于所有绘制方法中,如 drawimage、
//drawstring、draw 和 fill。 它指定新的像素如何在呈现过程中与图形设备上的现有像素组合。
g2d.setcomposite(ac);
完整代码(代码中注释足够了,就不多啰嗦)
package cumt.zry.two; import java.awt.*; import java.awt.image.bufferedimage; import java.io.*; import javax.imageio.*; public class watermark2{ public watermark2(){super();}; /** * 在源图片上设置水印文字 */ public void wordstoimage(string srcimagepath,float alpha, string font,int fontstyle,int fontsize,color color, string inputwords,int x,int y,string imageformat,string topath) throws ioexception{ fileoutputstream fos=null; try { //读取图片 bufferedimage image = imageio.read(new file(srcimagepath)); //创建java2d对象 graphics2d g2d=image.creategraphics(); //用源图像填充背景 g2d.drawimage(image, 0, 0, image.getwidth(), image.getheight(), null, null); //!!!! alphacomposite ac = alphacomposite.getinstance(alphacomposite.src_over, alpha); //为 graphics2d 上下文设置 composite。 composite 用于所有绘制方法中,如 drawimage、 //drawstring、draw 和 fill。 它指定新的像素如何在呈现过程中与图形设备上的现有像素组合。 g2d.setcomposite(ac); //设置文字字体名称、样式、大小 g2d.setfont(new font(font, fontstyle, fontsize)); g2d.setcolor(color);//设置字体颜色 g2d.drawstring(inputwords, x, y); //输入水印文字及其起始x、y坐标 g2d.dispose(); //将水印后的图片写入topath路径中 fos=new fileoutputstream(topath); imageio.write(image, imageformat, fos); } //文件操作错误抛出 catch (exception e) { e.printstacktrace(); }finally{ if(fos!=null){ fos.close(); } } } /** * 在源图像上设置图片水印 */ public void imagetoimage(string srcimagepath,string appendimagepath, float alpha,int x,int y,int width,int height, string imageformat,string topath) throws ioexception{ fileoutputstream fos = null; try { //读图 bufferedimage image = imageio.read(new file(srcimagepath)); //创建java2d对象 graphics2d g2d=image.creategraphics(); //用源图像填充背景 g2d.drawimage(image, 0, 0, image.getwidth(), image.getheight(), null, null); //关键地方 alphacomposite ac = alphacomposite.getinstance(alphacomposite.src_over, alpha); g2d.setcomposite(ac); bufferedimage appendimage = imageio.read(new file(appendimagepath)); g2d.drawimage(appendimage, x, y, width, height, null, null); g2d.dispose(); fos=new fileoutputstream(topath); imageio.write(image, imageformat, fos); } catch (exception e) { e.printstacktrace(); }finally{ if(fos!=null){ fos.close(); } } } public static void main(string[] args) throws exception { watermark2 imageobj = new watermark2(); //源图片路径 string srcimagepath = "f:/27.jpg"; //水印图片路径 string appendimagepath = "f:/logo.jpg"; // ---- 宋体 普通字体 77号字 红色 透明度0.4" float alpha = 0.4f; string font = "宋体"; int fontstyle = font.plain; int fontsize = 77; color color = color.red; string inputwords = "图片上设置水印文字"; int x = 1700; int y = 77; string imageformat = "jpg"; //水印文字后的存储路径 string wtopath = "f:/31.png"; //水印图片后的存储路径 string itopath = "f:/7.png" ; imageobj.wordstoimage(srcimagepath, alpha, font, fontstyle, fontsize, color, inputwords, x, y, imageformat, wtopath); imageobj.imagetoimage(srcimagepath, appendimagepath, alpha, x, y, 300, 200, imageformat, itopath); } }
实现预览:
以上就是文章的全部内容,希望对大家的学习有所帮助。