给图片格式的文件添加水印(jpg/jpeg/png)

本篇文章包括以下内容:

  1. 从本地读取文件添加水印并保存到本地的工具类。
  2. 改良的使用方法,从minio中读取图片添加水印,并使用文件输入流将文件返回给前端。

  1. 工具类
package testtttt;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

/** * Description: 图片水印工具类 * @authortengk * @version1.0 */
public class ImgWaterMarkUtil {

    // 水印透明度private static float alpha= 0.7f;
    // 水印横向位置private static int positionWidth= 150;
    // 水印纵向位置private static int positionHeight= 300;
    // 水印文字字体private static Font font= new Font("宋体", Font.BOLD, 20);
    // 水印文字颜色private static Color color= Color.white;

    //文字水印位置铺满全屏private static ArrayList position1;
    private static ArrayList position2;

    /**     *     * @paramalpha     *            水印透明度     * @parampositionWidth     *            水印横向位置     * @parampositionHeight     *            水印纵向位置     * @paramfont     *            水印文字字体     * @paramcolor     *            水印文字颜色     */public static void setImageMarkOptions(float alpha, int positionWidth,
                                           int positionHeight, Font font, Color color) {
        if (alpha != 0.0f) {
            ImgWaterMarkUtil.alpha = alpha;
        }
        if (positionWidth != 0) {
            ImgWaterMarkUtil.positionWidth = positionWidth;
        }
        if (positionHeight != 0) {
            ImgWaterMarkUtil.positionHeight = positionHeight;
        }
        if (font != null) {
            ImgWaterMarkUtil.font = font;
        }
        if (color != null) {
            ImgWaterMarkUtil.color = color;
        }
    }

    /**     * 给图片添加水印图片     *     * @paramiconPath     *            水印图片路径     * @paramsrcImgPath     *            源图片路径     * @paramtargerPath     *            目标图片路径     */public static void markImageByIcon(String iconPath, String srcImgPath,
                                       String targerPath) {
        markImageByIcon(iconPath, srcImgPath, targerPath, null);
    }

    /**     * 给图片添加水印图片、可设置水印图片旋转角度     *     * @paramiconPath     *            水印图片路径     * @paramsrcImgPath     *            源图片路径     * @paramtargerPath     *            目标图片路径     * @paramdegree     *            水印图片旋转角度     */public static void markImageByIcon(String iconPath, String srcImgPath,
                                       String targerPath, Integer degree) {
        OutputStream os = null;
        try {

            Image srcImg = ImageIO.read(new File(srcImgPath));

            BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
                    srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);

            // 1、得到画笔对象Graphics2D g = buffImg.createGraphics();

            // 2、设置对线段的锯齿状边缘处理g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);

            g.drawImage(
                    srcImg.getScaledInstance(srcImg.getWidth(null),
                            srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,
                    null);
            // 3、设置水印旋转if (null != degree) {
                g.rotate(Math.toRadians(degree),
                        (double) buffImg.getWidth() / 2,
                        (double) buffImg.getHeight() / 2);
            }

            // 4、水印图片的路径 水印图片一般为gif或者png的,这样可设置透明度ImageIcon imgIcon = new ImageIcon(iconPath);

            // 5、得到Image对象。Image img = imgIcon.getImage();

            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                    alpha));

            // 6、水印图片的位置g.drawImage(img, positionWidth, positionHeight, null);
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
            // 7、释放资源g.dispose();

            // 8、生成图片os = new FileOutputStream(targerPath);
            ImageIO.write(buffImg, "JPG", os);

            System.out.println("图片完成添加水印图片");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(null != os) {
                    os.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**     * 给图片添加水印文字     *     * @paramlogoText     *            水印文字     * @paramsrcImgPath     *            源图片路径     * @paramtargerPath     *            目标图片路径     */public static void markImageByText(String logoText, String srcImgPath,
                                       String targerPath,int allFlag) {
        markImageByText(logoText, srcImgPath, targerPath, null,allFlag);
    }

    /**     * 给图片添加水印文字、可设置水印文字的旋转角度     *     * @paramlogoText     * @paramsrcImgPath     * @paramtargerPath     * @paramdegree     */public static void markImageByText(String logoText, String srcImgPath,
                                       String targerPath, Integer degree,int allFlag) {

        InputStream is = null;
        OutputStream os = null;
        try {
            // 1、源图片Image srcImg = ImageIO.read(new File(srcImgPath));
            BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
                    srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);

            // 2、得到画笔对象Graphics2D g = buffImg.createGraphics();
            // 3、设置对线段的锯齿状边缘处理g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(
                    srcImg.getScaledInstance(srcImg.getWidth(null),
                            srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,
                    null);
            // 4、设置水印旋转if (null != degree) {
                g.rotate(Math.toRadians(degree),
                        (double) buffImg.getWidth() / 2,
                        (double) buffImg.getHeight() / 2);
            }
            // 5、设置水印文字颜色g.setColor(color);
            // 6、设置水印文字Fontg.setFont(font);
            // 7、设置水印文字透明度g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                    alpha));
            // 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)if (allFlag == 1){
                int width = srcImg.getWidth(null);
                int height = srcImg.getHeight(null);
                position1 = new ArrayList();
                position2 = new ArrayList();
                position1.add(0);
                position1.add(width/4);
                position1.add(width/2);
                position1.add(width*3/4);
                position1.add(width);
                position2.add(0);
                position2.add(height/4);
                position2.add(height/2);
                position2.add(height*3/4);
                position2.add(height);

                for (int i = 0; i < position1.size(); i++) {
                    for (int j = 0; j < position2.size(); j++) {
                        g.drawString(logoText,(Integer) position1.get(i),(Integer) position2.get(j));
                    }
                }
            }else {
                g.drawString(logoText,positionWidth,positionHeight);
            }

            // 9、释放资源g.dispose();
            // 10、生成图片os = new FileOutputStream(targerPath);
            ImageIO.write(buffImg, "JPG", os);

            System.out.println("图片完成添加水印文字");

        } catch (Exception e) {
            System.out.println("图片加水印失败");
            throw new RuntimeException("图片加水印失败");
        } finally {
            try {
                if (null == is) {
                } else {
                    is.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if (null != os) {
                    os.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {

        String markText = "cq-tengk "+new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        //图片测试String srcImgPath = "E:/ylnew/111.jpg";
        String targerTextPath2 = "E:/ylnew/3000.jpg";
        String targerTextPath = "E:/ylnew/3001.jpg";
        // 给图片添加水印文字markImageByText(markText, srcImgPath, targerTextPath,0);
        // 给图片添加水印文字,水印文字旋转-45markImageByText(markText, srcImgPath, targerTextPath2, -45,1);

        //文件测试//        String oldFile = "D:/tmp/tmp/20A00053公开招标(定稿).doc";//        String newFile = "D:/tmp/res/20A00053公开招标(定稿).doc";//        String oldFile = "D:/tmp/tmp/5G专网产品资费设计.docx";//        String newFile = "D:/tmp/res/5G专网产品资费设计.docx";//        String oldFile = "D:/tmp/tmp/2.xlsx";//        String newFile = "D:/tmp/res/22.xlsx";String oldFile = "D:/tmp/tmp/2.pdf";
        String newFile = "D:/tmp/res/22.pdf";
//        String oldFile = "D:/tmp/tmp/2.pptx";//        String newFile = "D:/tmp/res/2.pptx";//        OfficeWaterMarkUtil.addWaterMarkOffice(oldFile,newFile,markText);}

}
  1. service层使用示例,以文件流形式返回
// 图片水印方法@Override
    public void getWatermarkedFile(String sourceObjectPath, HttpServletResponse response) {

        System.out.println("sourceObjectPath: " + sourceObjectPath);
        // 检查源桶中的文件是否存在boolean objectExists = false;
        try {
            minioClient.statObject(
                    StatObjectArgs.builder()
                            .bucket(minIOWatermarkConfig.getBucketName())
                            .object(sourceObjectPath)
                            .build()
            );
            objectExists = true; // 如果没有抛出异常,则对象存在} catch (ErrorResponseException e) {
            if ("NoSuchKey".equals(e.errorResponse().code())) {
                System.err.println("源文件不存在: " + minIOWatermarkConfig.getBucketName() + "/" + sourceObjectPath);
                return; // 结束方法执行,因为源文件不存在} else {
                throw new RuntimeException(e);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        // 如果文件存在,执行后续操作if (objectExists) {
            try {
                // 下载文件到临时文件  图片处理逻辑File tempFile = File.createTempFile("temp", ".tmp");
                minioClient.downloadObject(
                        DownloadObjectArgs.builder()
                                .bucket(minIOWatermarkConfig.getBucketName())
                                .object(sourceObjectPath)
                                .filename(tempFile.getAbsolutePath())
                                .build()
                );

                // 添加水印String markText = ImgWaterMarkUtil.markText;
                String targetWatermarkedFilePath = tempFile.getAbsolutePath() + "_watermarked";
                
                if (sourceObjectPath.endsWith(".png") || sourceObjectPath.endsWith(".jpg")){
                    ImgWaterMarkUtil.markImageByText(markText, tempFile.getAbsolutePath(), targetWatermarkedFilePath, -45, 1);
                }else {
                    log.error("文件类型暂不支持添加水印");
                    return;
                }

                // 设置响应头信息String contentType = "application/octet-stream"; // 默认为二进制流,适用于未知的文件类型String fileName = sourceObjectPath;
                String lowerCaseFileName = fileName.toLowerCase();
                if (lowerCaseFileName.endsWith(".png")) {
                    contentType = "image/png"; // PNG 图片} else if (lowerCaseFileName.endsWith(".jpg") || lowerCaseFileName.endsWith(".jpeg")) {
                    contentType = "image/jpeg"; // JPG 图片//                } else if (lowerCaseFileName.endsWith(".gif")) {//                    contentType = "image/gif"; // GIF 图片}
                response.setContentType(contentType);
                response.setHeader("Content-Disposition", "attachment; filename=\"" + tempFile.getName() + "\"");
//                response.setHeader("Content-Disposition", "inline; filename=\"" + tempFile.getName() + "\"");    attachment 下载  inline显示// 通过临时文件路径获取加水印后的文件File watermarkedFile = new File(targetWatermarkedFilePath);
                System.out.println(fileName);
                // 使用文件输入流读取文件返回到服务端try (InputStream inputStream = new FileInputStream(watermarkedFile);
                     OutputStream outputStream = response.getOutputStream()) {
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                    outputStream.flush();
                }

                // 删除临时文件tempFile.delete();
                new File(targetWatermarkedFilePath).delete();

            } catch (Exception e) {
                // 异常处理log.error("Error processing file", e);
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            }
        }
    }
点赞

当前页面评论已关闭。

隐藏
变装