/*** 添加水印* @param inputStream 图片文件流* @param mark 要打的水印* @param rgb 字体颜色(白色)* @param alpha 分辨率* @param degree 水印旋转* @return*/public static InputStream addMark(InputStream inputStream, String mark,Integer rgb,Float alpha,Integer fontSize,Integer degree) {if(Objects.isNull(rgb)){rgb = 0xffffff;}if(Objects.isNull(alpha)){alpha = 1F;}if(Objects.isNull(fontSize)){fontSize = 60;}String[] waterMarkContents = mark.split("\\|\\|");// 用来调整水印的间距int space = 20;//将读取流转化为图片对象Image srcImg = null;try {srcImg = ImageIO.read(inputStream);} catch (IOException e) {throw new RuntimeException(e);}//获取图片的宽int srcImgWidth = srcImg.getWidth(null);//获取图片的高int srcImgHeight = srcImg.getHeight(null);System.out.println("图片的宽:" + srcImgWidth);System.out.println("图片的高:" + srcImgHeight);BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);// 加水印//创建画笔Graphics2D g = bufImg.createGraphics();//设置对线段的锯齿状边缘处理g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);//srcImg 为上面获取到的原始图片的图片对象g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);//设置水印旋转if (null != degree) {g.rotate(Math.toRadians(degree),(double) bufImg.getWidth() / 2,(double) bufImg.getHeight() / 2);}//根据图片的背景设置水印颜色g.setColor(new Color(rgb));g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));//设置字体 画笔字体样式为微软雅黑,加粗,文字大小为60ptg.setFont(new Font("微软雅黑", Font.BOLD, fontSize));java.util.List<String> waterMarkContentList = new ArrayList<>(); // 将换行后的文字放入新的集合for (String markContent : waterMarkContents) {// 单字符长度int tempCharLen = 0;// 单行字符总长度临时计算int tempLineLen = 0;StringBuilder sb = new StringBuilder();for (int i = 0; i < markContent.length(); i++) {char tempChar = markContent.charAt(i);tempCharLen = getCharLen(tempChar, g);tempLineLen += tempCharLen;// 文字长度大于图片宽度-2*间距-字体大小if (tempLineLen > srcImgWidth - space * 2 - tempCharLen) {// 长度已经满一行waterMarkContentList.add(sb.toString());// 清空内容,重新追加sb.delete(0, sb.length());tempLineLen = 0;}// 追加字符sb.append(tempChar);}waterMarkContentList.add(sb.toString());}// 绘制水印int tempY = fontSize + space;for (int i = 0; i < waterMarkContentList.size(); i++) {String s = waterMarkContentList.get(i);//左上角 // g.drawString(s, space, i * tempY + 3 * space);//右下角g.drawString(s, space, srcImgHeight - (waterMarkContentList.size() - i) * tempY + space);// g.drawString(s, space, (srcImgHeight - (waterMarkContentList.size() - i) * (tempY*2))/2 + space);//设置水印的坐标 // int x = (srcImgWidth - getWatermarkLength(mark, g)) / 2; // int y = srcImgHeight / 2;//画出水印 第一个参数是水印内容,第二个参数是x轴坐标,第三个参数是y轴坐标 // g.drawString(s, x, y);}g.dispose();ByteArrayOutputStream baos = new ByteArrayOutputStream();try {ImageIO.write(bufImg,"jpg",baos);} catch (IOException e) {throw new RuntimeException(e);}return new ByteArrayInputStream(baos.toByteArray());}/*** 添加水印 并且等比缩(等比压缩图片)* @param inputStream* @param mark* @return*/public static InputStream addMarkValue(InputStream inputStream, String mark,Integer rgb,Float alpha,Integer fontSize,Integer degree) {if(Objects.isNull(rgb)){rgb = 0xffffff;}if(Objects.isNull(alpha)){alpha = 1F;} // if(Objects.isNull(fontSize)){ // fontSize = 60; // }if(Objects.isNull(fontSize)){fontSize = 30;}String[] waterMarkContents = mark.split("\\|\\|");// 用来调整水印的间距int space = 20;//将读取流转化为图片对象Image srcImg = null;try {srcImg = ImageIO.read(inputStream);} catch (IOException e) {throw new RuntimeException(e);}// 等比缩int srcImgWidth = srcImg.getWidth(null);;int srcImgHeight = srcImg.getHeight(null);//如果图片本身的宽和高均小于要压缩到的宽和高,则不压缩直接返回if(800>srcImg.getWidth(null)&&800>srcImg.getHeight(null)){srcImgWidth =800;srcImgHeight =800;}else{//宽和高等比缩放的率double rate1=(double)srcImg.getWidth(null)/(double)800;double rate2=(double)srcImg.getHeight(null)/(double)800;//控制缩放大小double rate=rate1<rate2 ? rate1:rate2;srcImgWidth=(int) (srcImg.getWidth(null)/rate);srcImgHeight=(int) (srcImg.getHeight(null)/rate);}//获取图片的宽 // int srcImgWidth = srcImg.getWidth(null); // //获取图片的高 // int srcImgHeight = srcImg.getHeight(null);// 设置图片固定大小 // int srcImgWidth = 1080; // 目标宽度 // int srcImgHeight = 2400; // 目标高度System.out.println("图片的宽:" + srcImgWidth);System.out.println("图片的高:" + srcImgHeight);BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);//===============图片开始压缩=======================//通过比例压缩float scale = 0.6f;//压缩之后的长度和宽度int doWithHeight = (int) (scale * srcImgHeight);int dowithWidth = (int) (scale * srcImgWidth);// 图片压缩bufImg.getGraphics().drawImage(bufImg.getScaledInstance(dowithWidth, doWithHeight, java.awt.Image.SCALE_SMOOTH), 0, 0, null);//===============图片结束压缩=======================// 加水印//创建画笔Graphics2D g = bufImg.createGraphics();//设置对线段的锯齿状边缘处理g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);//srcImg 为上面获取到的原始图片的图片对象g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);//设置水印旋转if (null != degree) {g.rotate(Math.toRadians(degree),(double) bufImg.getWidth() / 2,(double) bufImg.getHeight() / 2);}//根据图片的背景设置水印颜色g.setColor(new Color(rgb));g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));//设置字体 画笔字体样式为微软雅黑,加粗,文字大小为60ptg.setFont(new Font("微软雅黑", Font.BOLD, fontSize));java.util.List<String> waterMarkContentList = new ArrayList<>(); // 将换行后的文字放入新的集合for (String markContent : waterMarkContents) {// 单字符长度int tempCharLen = 0;// 单行字符总长度临时计算int tempLineLen = 0;StringBuilder sb = new StringBuilder();for (int i = 0; i < markContent.length(); i++) {char tempChar = markContent.charAt(i);tempCharLen = getCharLen(tempChar, g);tempLineLen += tempCharLen;// 文字长度大于图片宽度-2*间距-字体大小if (tempLineLen > srcImgWidth - space * 2 - tempCharLen) {// 长度已经满一行waterMarkContentList.add(sb.toString());// 清空内容,重新追加sb.delete(0, sb.length());tempLineLen = 0;}// 追加字符sb.append(tempChar);}waterMarkContentList.add(sb.toString());}// 绘制水印int tempY = fontSize + space;for (int i = 0; i < waterMarkContentList.size(); i++) {String s = waterMarkContentList.get(i);//左上角 // g.drawString(s, space, i * tempY + 3 * space);//右下角g.drawString(s, space, srcImgHeight - (waterMarkContentList.size() - i) * tempY + space);// g.drawString(s, space, (srcImgHeight - (waterMarkContentList.size() - i) * (tempY*2))/2 + space);//设置水印的坐标 // int x = (srcImgWidth - getWatermarkLength(mark, g)) / 2; // int y = srcImgHeight / 2;//画出水印 第一个参数是水印内容,第二个参数是x轴坐标,第三个参数是y轴坐标 // g.drawString(s, x, y);}// 设置透明度,0.5 表示半透明AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f);g.setComposite(alphaComposite);String text ="现场拍照";g.setStroke(new BasicStroke(10)); // g.setFont(new Font("微软雅黑", Font.BOLD, 300)); // 没有压缩图片设置现场拍照大小 // g.setFont(new Font("方正粗黑宋简体", Font.PLAIN, 120));// 压缩后设置现场拍照大小g.setFont(new Font("方正粗黑宋简体", Font.PLAIN, 150));int x = (srcImgWidth - getWatermarkLength(text, g)) / 2;int y = srcImgHeight/2;g.setColor(new Color(0x80000000));g.drawString(text, x, y);/* 添加水印的文字和设置水印文字出现的内容 ----位置 */ // g.drawString(iter, width - w, height - h); // g.setFont(new Font(Font.DIALOG_INPUT,Font.BOLD+Font.PLAIN, 200));g.dispose();ByteArrayOutputStream baos = new ByteArrayOutputStream();try {ImageIO.write(bufImg,"jpg",baos);} catch (IOException e) {throw new RuntimeException(e);}return new ByteArrayInputStream(baos.toByteArray());}/*** 获取水印文字的长度* @param waterMarkContent* @param g* @return*/private static int getWatermarkLength(String waterMarkContent, Graphics2D g) {return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());}private static int getCharLen(char c, Graphics2D g) {return g.getFontMetrics(g.getFont()).charWidth(c);}//河北省 红色:0xff0000public static void main(String[] args) {try {InputStream inputStream = new FileInputStream("D:\\IMG_20231123_115406.jpg");InputStream inputStream1 = addMarkValue(inputStream, "经度:114.498895||" +"纬度:38.001944||" +"地址: 赵陵铺街道||"+"时间:2022/10/6 14:26:01 ||" +"海拔:0.0米 ||" + // "天气:17-24C 北风 ||" +"备注:服务中备餐区",null,0.6F,null,null);String tarImgPath="D:\\tool2.jpg";FileOutputStream outImgStream = new FileOutputStream(tarImgPath);byte[] buf = new byte[1024];int le = -1;while (( le = inputStream1.read(buf))!=-1){outImgStream.write(buf,0,le);}} catch (Exception e) {throw new RuntimeException(e);}}