有些图片用前面的代码加水印的时候出现位置不对的问题,排查后发现是jpeg格式图片会出现问题
因为jpeg图片的特殊性 导致绘制的水印位置不对,所以要单独对jpeg图片进行处理
记录一下解决方法
1.图片格式识别
//先获取文件类型
ImageInputStream iis = ImageIO.createImageInputStream(new File(srcPath));
Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(iis);
String imageType = "";
while (imageReaders.hasNext()) {
ImageReader reader = imageReaders.next();
imageType = reader.getFormatName().toLowerCase();
}
String[] imageList = {"png", "jpeg","jpg","png","bmp"};
List<String> imageArray = Arrays.asList(imageList);
if (!imageArray.contains(imageType)){
System.out.println(imageType + "文件类型不能转换");
}
2.位置偏移来自于旋转 分别处理
// 旋转文字
AffineTransform affineTransform = g.getTransform();
//不是jpeg格式可以用这个旋转
if (!"jpeg".equals(imageType)){
affineTransform.rotate(Math.toRadians(-30), 0, 0);
}
Font rotatedFont = font.deriveFont(affineTransform);
// 计算文字宽高度
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
int textWidth = metrics.stringWidth(content); // 文字宽度
int textHeight = metrics.getHeight(); // 文字高度
// 计算文字坐标
int x = (width - textWidth) / 2;
//如果超出图片宽度
while ((textWidth+x)>width){
//防止死循环
if (textWidth>width){
x = 0;break;
}
x = x / 2;
}
//水印x轴宽度
int y_textHeigh = (int) (textWidth * Math.cos(Math.toRadians(60.0)));
int y = (height + y_textHeigh) / 2;
//jpeg单独处理
if ("jpeg".equals(imageType)){ // 旋转偏移纠正
//水印旋转y轴高度
int y_textWidth = (int) (textWidth * Math.cos(Math.toRadians(30.0)));
//图片宽高比
double wHRatio = width / (double)height ;
//水印向左偏移量 0.8 是再向左偏移看起来比较好,不乘0.8水印也不会到图片外
double xLeftMove = ((width - y_textWidth) /2.0)*0.8;
//宽比高多可以单独处理
if (wHRatio>1){
//水印偏移
g.translate(- ((0.3 * width) - xLeftMove), height * 0.1);
}else {
//0.4 和0.5这个数值,是用零点位置和不同图片比例算出来的
double x_wRatio = 0.4 + (((1 - wHRatio) / 0.3) *0.1);
double y_hRatio = 0.5 - x_wRatio;
g.translate(- ((x_wRatio * width)- xLeftMove), height * (y_hRatio<0?0:y_hRatio));
}
//旋转30度
g.rotate(-30*Math.PI/180);
}
//绘制水印
g.drawString(content, x, y);