/** * 添加水印 * @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)); //设置字体 画笔字体样式为微软雅黑,加粗,文字大小为60pt g.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)); //设置字体 画笔字体样式为微软雅黑,加粗,文字大小为60pt g.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); } //河北省 红色:0xff0000 public 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); } }