以下是根据byte[]对象来进行文字水印的添加,主要涉及的就是图像对象如何与byte[]数组转换的问题,还是使用图像画笔进行的水印添加,水印文字添加在图像的正中央。
可根据需要修改水印字体样式和透明度。代码如下:
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
/**
* 文字水印
* 参考 http://sjsky.iteye.com/blog/1154390
* 参考
*/
public class ImageMarkLogoByText {
/**
* @param args
*/
public static void main(String[] args) {
String srcImgPath = "d:/01.jpg";
String logoText = "[ 测试文字水印 http://ask.csdn.net]";
String targerPath = "d:/img_mark_text.jpg";
// 现在已知的是图片路径,所以需要自己转换成byte数组,如果你有byte数组直接使用下面的方法
byte[] srcImgByte = changeImg2Byte(srcImgPath);
// 给图片添加水印,需要传入文字和图片的byte数组,返回结果是加了水印的图片byte[]对象
byte[] resultByte = ImageMarkLogoByText
.markByText(logoText, srcImgByte);
// 为了便于查看,下面对结果进行了输出
BufferedImage resultImage = changeByte2Img(resultByte);
try {
ImageIO.write(resultImage, "JPG", new FileOutputStream(targerPath));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 根据传入的图像文件路径读取图像,并存入到byte数组中。
*
* @param srcImgPath
* @return
*/
private static byte[] changeImg2Byte(String srcImgPath) {
// TODO Auto-generated method stub
try {
BufferedImage image = ImageIO.read(new File(srcImgPath));
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", out);
byte[] b = out.toByteArray();
return b;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 给图片添加文字水印
*
* @param logoText
* @param srcByteImg
*/
public static byte[] markByText(String logoText, byte[] srcByteImg) {
InputStream is = null;
ByteArrayOutputStream os = null;
try {
// 获取image对象,没有他做不了绘制
BufferedImage buffImg = changeByte2Img(srcByteImg);
// 得到画笔对象
Graphics2D g = buffImg.createGraphics();
// 设置对线段的锯齿状边缘处理
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
int width = buffImg.getWidth(null);
int height = buffImg.getHeight(null);
g.drawImage(buffImg.getScaledInstance(width, height,
Image.SCALE_SMOOTH), 0, 0, null);
// 设置颜色
g.setColor(Color.red);
// 设置 Font
g.setFont(new Font("宋体", Font.BOLD, 30));
FontMetrics fontMetrics = g.getFontMetrics();
int logoWidth = fontMetrics.stringWidth(logoText);
// 设置水印的透明度
float alpha = 0.5f;
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
alpha));
// 第一参数->设置的内容,后面两个参数->文字左上角在图片上的坐标位置(x,y),简单点设置文字在中心,竖直方向有些偏差 .
g.drawString(logoText, (width - logoWidth) / 2, height / 2
+fontMetrics.getAscent()/2 - fontMetrics.getDescent()/2);
g.dispose();
// 生成图片
os = new ByteArrayOutputStream();
ImageIO.write(buffImg, "JPG", os);
System.out.println("图片完成添加文字印章。。。。。。");
// 返回图片的byte数组
return os.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != is)
is.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if (null != os)
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* 根据传入的图像byte数组转换成图像
*
* @param srcByteImg
* @return
*/
private static BufferedImage changeByte2Img(byte[] srcByteImg) {
// TODO Auto-generated method stub
ByteArrayInputStream in = new ByteArrayInputStream(srcByteImg);
try {
BufferedImage image = ImageIO.read(in);
return image;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
原始图像:
结果图像: