java 图片水印、压缩图片、宽和高等比缩放的率

发布时间:2023年12月18日
   /**
     * 添加水印
     * @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);
        }

    }


文章来源:https://blog.csdn.net/qq_38432390/article/details/134988989
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。