package com.zhx.util.imgutil; import com.zhx.util.stringutil.ArithUtil; import net.coobird.thumbnailator.Thumbnails; import net.coobird.thumbnailator.filters.Watermark; import net.coobird.thumbnailator.geometry.Positions; import sun.font.FontDesignMetrics; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Iterator; public class ImgHandle { public static void main(String[] args) { String filePath = "C:\Users\admin\Desktop\3333.jpg"; String newFilePath = "C:\Users\admin\Desktop\33d333ada1111.png"; // boolean sc2 = waterMarkWithText(filePath, newFilePath, "https://licd.beijing2022.cn", 1f, 1.0f, 1000, 1000, 1); boolean sc23 = autoWaterMarkWithText(filePath, newFilePath, "licd.beijing2022.cn", 250, 250, 1.0f, 1); } /** * 图片缩放加水印 * * @param filePath 原图路径 * @param newFilePath 处理后新图片路径 * @param waterMarkPath 水印图片路径 * @param scale 比例(0.1- 1.0) * @param transparency 水印透明度 */ public static boolean waterMark(String filePath, String newFilePath, String waterMarkPath, float scale, float transparency) { try { Thumbnails.of(filePath) .scale(scale). watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(waterMarkPath)), transparency).toFile(newFilePath); return true; } catch (IOException e) { e.printStackTrace(); return false; } } /** * 图片天加文字水印(默认缩小scale) * 备注: * Positions.BOTTOM_RIGHT 表示水印位置 * * @param filePath 原图路径 * @param newFilePath 处理后新图片路径 * @param markText 水印文字 * @param scale 比例(0.1- 1.0) * @param transparency 水印透明度 * @param type 1 按比例 2按宽高 * @param widthSize 缩放宽 * @param heightSize 缩放高 */ public static boolean waterMarkWithText(String filePath, String newFilePath, String markText, float scale, float transparency, int widthSize, int heightSize, int type) { try { //先进行图片缩放 if (type == 1) { imgScale(scale, filePath, newFilePath); } else { imgSize(widthSize, heightSize, filePath, newFilePath); } //获取缩放图分辨率 File file = new File(newFilePath); BufferedImage imgBi = null; try { imgBi = ImageIO.read(file); } catch (Exception e) { e.printStackTrace(); } //图片原始宽度 int width = imgBi.getWidth(); //图片原始高度 int height = imgBi.getHeight(); //计算右下角水印高宽 int waterWidth = new Double(width * 0.75).intValue(); int waterWidth2 = new Double(width * 0.5).intValue(); int waterHeight = new Double(height).intValue(); ImgHandle im = new ImgHandle(); String randomNum = "NO." + String.valueOf(System.currentTimeMillis()); if (randomNum.length() > 16) { randomNum = randomNum.substring(0, 16); } BufferedImage bi = im.apply(imgBi, waterWidth, waterHeight, markText, 1, randomNum); BufferedImage bi2 = im.apply(imgBi, waterWidth2, waterHeight, randomNum, 1, markText); Watermark watermark = new Watermark(Positions.BOTTOM_LEFT, bi, transparency); Watermark watermark2 = new Watermark(Positions.BOTTOM_RIGHT, bi2, transparency); Thumbnails.of(newFilePath).scale(1). watermark(watermark).toFile(newFilePath); watermark2(watermark2, newFilePath); return true; } catch (IOException e) { e.printStackTrace(); return false; } } /** * 生成的水印 * * @param img * @return */ public BufferedImage apply(BufferedImage img, int waterWidth, int waterHeight, String markText, float scale, String markText2) { int width = img.getWidth(); int height = img.getHeight(); BufferedImage imgWithWatermark = new BufferedImage(waterWidth, waterHeight, BufferedImage.TYPE_INT_RGB); Graphics2D g = imgWithWatermark.createGraphics(); //设置透明 start imgWithWatermark = g.getDeviceConfiguration().createCompatibleImage(waterWidth, waterHeight, Transparency.TRANSLUCENT); g = imgWithWatermark.createGraphics(); g.setColor(new Color(159, 160, 160)); //设置透明 end int[] sizes = new int[]{60, 30, 20, 16, 14, 9, 8, 6, 4}; int contentLength = 0; Font font = null; for (int i = 0; i < 8; i++) { //设置字体及大小 font = new Font("Helvetica", Font.BOLD, sizes[i]); g.setFont(font); g.drawRect(0, 0, 0, 0); contentLength = getWatermarkLength(markText + markText2, g); if (contentLength < width) { //找到最合适的字体 int contentLength2 = getWatermarkLength(markText, g); // System.out.println("水印长度contentLength2----" + contentLength2); break; } } //设置水印的坐标 FontDesignMetrics metrics = FontDesignMetrics.getMetrics(g.getFont()); int fontHeight = metrics.getHeight(); char[] data = markText.toCharArray(); //x1水印1距离左边距和底边距 //x2水印2距离右边距和底边距 int x1 = 0; int x2 = 0; if (width > 500) { x1 = 20; } else { x1 = 8; } int y = waterHeight - x1; // System.out.println("水印高度waterHeight----"+waterHeight); // System.out.println("字体高度fontHeight----"+fontHeight); x2 = width / 2 - getWatermarkLength(markText, g) - x1; if (markText.contains("beijing2022")) { // System.out.println("距离中心位置x1:----" + x1); // System.out.println("距离顶部位置y:----" + y); g.drawChars(data, 0, data.length, x1, y); } else { // System.out.println("距离中心位置x2:----" + x2); // System.out.println("距离顶部位置y:----" + y); g.drawChars(data, 0, data.length, x2, y); } return imgWithWatermark; } /** * 缩放 * * @param scale * @param filePath * @param newFilePath * @return */ public static boolean imgScale(float scale, String filePath, String newFilePath) { try { Thumbnails.of(filePath).scale(scale).toFile(newFilePath); return true; } catch (IOException e) { e.printStackTrace(); return false; } } /** * 大小缩放 * * @param width * @param height * @param filePath * @param newFilePath * @return */ public static boolean imgSize(int width, int height, String filePath, String newFilePath) { try { Thumbnails.of(filePath).size(width, height).toFile(newFilePath); return true; } catch (IOException e) { e.printStackTrace(); return false; } } public static boolean watermark2(Watermark watermark2, String filePath) { try { Thumbnails.of(filePath).scale(1). watermark(watermark2).toFile(filePath); return true; } catch (IOException e) { e.printStackTrace(); return false; } } /** * 计算水印文字宽度 * * @param waterMarkContent * @param g * @return */ public static int getWatermarkLength(String waterMarkContent, Graphics2D g) { return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length()); } /** * @param filePath * @param newFilePath * @param markText * @param minWidth 文件缩放宽 * @param minHeight 文件缩放高 * @param transparency * @param addWater 是否用加水印1是2否 * @return */ public static boolean autoWaterMarkWithText(String filePath, String newFilePath, String markText, int minWidth, int minHeight, float transparency, int addWater) { String fileP = filePath; try { //获取原图分辨率
//https://www.cnblogs.com/SimonHu1993/p/9396375.html RotateImage.RotateImg(filePath, newFilePath); fileP = newFilePath; } catch (Exception e) { e.printStackTrace(); } File file = new File(fileP); BufferedImage imgBi = null; try { imgBi = ImageIO.read(file); } catch (Exception e) { e.printStackTrace(); } // 图片原始宽度 int width = imgBi.getWidth(); int height = imgBi.getHeight(); double min = ArithUtil.getDouble(String.valueOf(minWidth)); double real = ArithUtil.getDouble(String.valueOf(width)); float scale = (float) ArithUtil.div(min, real, 5); //缩放规则1 按比例 2按宽高 int type = 1; if (minWidth != 0 && minHeight != 0) { type = 2; //如果按比例缩放的高度大于要求高度再缩放高 double realHeight = ArithUtil.getDouble(String.valueOf(height)); float afterHeight = (float) ArithUtil.mul(realHeight, scale); if (afterHeight > minHeight) { float scale2 = (float) ArithUtil.div(minHeight, afterHeight, 5); minWidth = new Double(minWidth * scale2).intValue(); afterHeight = minHeight; } minHeight = (int) afterHeight; } Boolean result = false; //最大的缩略图上加水印,其他的缩略图在加完水印的缩略图上进行压缩 if (addWater == 1) { result = waterMarkWithText(fileP, newFilePath, markText, scale, transparency, minWidth, minHeight, type); } else if (addWater == 2) { result = imgSize(minWidth, minHeight, fileP, newFilePath); } return result; } /** * 图片缩放 * * @param filePath 图片路径 * @param newFilePath 缩略图路径 * @param scale 比例(0.1- 1.0) * @return */ public static boolean scaleImg(String filePath, String newFilePath, float scale) { try { Thumbnails.of(filePath).scale(scale).toFile(newFilePath); } catch (IOException e) { e.printStackTrace(); return false; } return true; } /** * 获得图片的格式,例如:JPEG、GIF等 * * @param file * @return */ public static String getImageFormat(File file) { try { ImageInputStream iis = ImageIO.createImageInputStream(file); Iterator<ImageReader> iterator = ImageIO.getImageReaders(iis); while (iterator.hasNext()) { ImageReader reader = iterator.next(); return reader.getFormatName().toLowerCase(); } } catch (IOException e) { e.printStackTrace(); } return null; } }
贴上横竖效果图: