java 显示水印增加

给图片增加盲水印 

亲测有效,有任何问题可以留言

/**
     * 添加文字水印的方法
     * 带下超过20M 和图片像素超过 9999的直接拒绝
     *
     * @param pressText 要添加的文字
     * @param fileId    文件Id
     * @param fontName  文字的字体名称
     * @param fontSize  文字的大小
     * @param fontColor 文字的颜色
     * @return
     */
    public void generateText(InputStream inputStream, String pressText, String fontName, int fontSize, String fontColor, int dissolve, Integer watermarkDegree, int batch, HttpServletResponse response, int inline) {

        try {
            BufferedImage bgImage = ImageIO.read(inputStream);
            long startTime = System.currentTimeMillis();
            int wideth = bgImage.getWidth(null);
            int height = bgImage.getHeight(null);
            BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = image.createGraphics();
            g.drawImage(bgImage, 0, 0, wideth, height, null);
            //设置字体大小、颜色等
            Font font = new Font(fontName, Font.PLAIN, fontSize);
            g.setColor(parseToColor(fontColor));
            g.setFont(font);

            //不加的话文字水印有锯齿
            RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            rh.put(RenderingHints.KEY_STROKE_CONTROL
                    , RenderingHints.VALUE_STROKE_PURE);
            rh.put(RenderingHints.KEY_ALPHA_INTERPOLATION
                    , RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g.setRenderingHints(rh);

            // 设置水印旋转角度
            if (null != watermarkDegree) {
                // 设置水印旋转
                g.rotate(Math.toRadians(watermarkDegree), (double) image.getWidth() / 2, (double) image.getHeight() / 2);
            }
            //设置是否平铺
            if (PaintModeEnum.TILED.eq(batch)) {
                // 设置水印透明度
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, dissolve / 100f));

                String[] waterMarkContents = pressText.split("\\|\\|");
                // 获取其中最长的文字水印的大小
                int maxLen = 0;
                int maxHigh = 0;
                for (int i = 0; i < waterMarkContents.length; i++) {
                    pressText = waterMarkContents[i];
                    int fontlen = getWatermarkLength(pressText, g);
                    if (fontlen >= maxLen) {
                        maxLen = fontlen;
                    }
                    maxHigh = maxHigh + (i + 1) * fontSize + 10;
                }
                // 文字长度相对于图片宽度应该有多少行
                int line = wideth * 2 / maxLen;
                int co = height * 2 / maxHigh;

                int yz = 0;
                // 填充Y轴方向
                for (int a = 0; a < co; a++) {
                    int t = 0;
                    for (int j = 0; j < waterMarkContents.length; j++) {
                        pressText = waterMarkContents[j];
                        int y = (j + 1) * fontSize + 10 + t;

                        // 文字叠加,自动换行叠加,注意符号
                        int tempX = -wideth / 2;
                        int tempY = -height / 2 + y + yz;
                        // 单字符长度
                        int tempCharLen = 0;
                        // 单行字符总长度临时计算
                        int tempLineLen = 0;
                        StringBuffer sb = new StringBuffer();
                        for (int i = 0; i < pressText.length(); i++) {
                            char tempChar = pressText.charAt(i);
                            tempCharLen = getCharLen(tempChar, g);
                            tempLineLen += tempCharLen;

                            // 和图片的长度进行对应的比较操作
                            if (tempLineLen >= wideth) {
                                // 长度已经满一行,进行文字叠加
                                g.drawString(sb.toString(), tempX, tempY);
                                t = t + fontSize;
                                // 清空内容,重新追加
                                sb.delete(0, sb.length());
                                tempY += fontSize;
                                tempLineLen = 0;
                            }
                            // 追加字符
                            sb.append(tempChar);
                        }
                        // 填充X轴
                        for (int z = 0; z < line; z++) {
                            // 最后叠加余下的文字
                            g.drawString(sb.toString(), tempX, tempY);
                            tempX = tempX + maxLen + 80;
                        }
                    }
                    yz = yz + maxHigh + 80;
                }
            } else {
                // 设置水印透明度
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, dissolve / 100f));
                g.drawString(pressText, wideth / 2, height / 2);
            }
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
            g.dispose();

            log.info("增加显示水印 耗时 cost :{}", System.currentTimeMillis() - startTime);

            String fileNameEncoder = URLEncoder.encode("target.jpg", "UTF-8");
            fileNameEncoder = fileNameEncoder.replaceAll("\\+", "%20");

            response.setContentType(FileNameUtil.getFileHttpContentType("target.jpg"));
            //嵌入到浏览器中打开
            if (InlineEnum.URL_INLINE.eq(inline)) {
                response.setHeader("Content-Disposition", "inline;Filename=" + fileNameEncoder);
            } else {
                response.setHeader("Content-Disposition", "attachment;Filename=" + fileNameEncoder);
            }
            //设置缓存
            response.setHeader("Cache-Control", "public, max-age=31536000");
            response.setHeader("Pragma", "Pragma");
            OutputStream output = response.getOutputStream();
            ImageIO.write(image, "jpg", output);

        } catch (Exception e) {
            log.error("增加显示水印失败 e :{}", e);
        }
    }

基本所有的显示水印的要求都能满足 !!!

 

原创不易,多谢关注 !

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值