图片加水印自动缩放的三种方式, 支持jpg, png, gif

牧云@^-^@ 提交于 2020-08-15 06:35:54

JAVA 自带图片处理, 不支持gif, png  会变黑, 需要处理

/**
 * 添加图片水印
 * 水印固定为 @xxxxxx  角标
 * @param srcFile
 * @return
 */
public static File addWaterMark(File srcFile) {

    OutputStream os = null;
    try {
        // 源图片
        String formatName = FileType.getSuffixByFilename(srcFile.getName()).substring(1);
        if (!FileType.JPG.equalsIgnoreCase(formatName)) {
            // 暂不支持其他类型的图片
            return srcFile;
        }
        Image srcImg = ImageIO.read(srcFile);
        BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
                srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
        int srcImgWidth = buffImg.getWidth(); // 图片宽
        int srcImgHeight = buffImg.getHeight(); // 图片高
        // 1、得到画笔对象
        Graphics2D g = buffImg.createGraphics();

        // 2、设置对线段的锯齿状边缘处理
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        // 3、画原图
        g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,1.0f));
        // 4、水印图片的路径 水印图片一般为gif或者png的,这样可设置透明度
        InputStream in =  getImageStream(iconPath);
        if (in == null) {
            log.warn("iconPath 获取网络图片失败: " + iconPath);
            return srcFile;
        }
        // 5、得到Image对象
        BufferedImage imgIconBufferedImage = ImageIO.read(in);
        ImageIcon imgIcon = new ImageIcon(imgIconBufferedImage);
        // 标准尺寸边距是 20px 标准图片大小 750 比例缩放
        int margin = scale(10, srcImgWidth);
        int width =  scale(imgIcon.getIconWidth(), srcImgWidth);
        int height = scale(imgIcon.getIconHeight(), srcImgWidth);
        int positionX = srcImgWidth - width -  margin ;
        int positionY = srcImgHeight - height -  margin ;
        // 6、水印图片的位置
        g.drawImage(imgIconBufferedImage, positionX, positionY, width, height,null);
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
        // 7、释放资源
        g.dispose();
        // 8、生成图片
        os = new FileOutputStream(srcFile.getAbsolutePath());
        ImageIO.write(buffImg, formatName, os);
    } catch (Exception e) {
        log.error("Exception" , e);
    } finally {
        try {
            if (null != os) {
                os.close();
            }
        } catch (Exception e) {
            log.error("close Exception" , e);
        }
    }
    return srcFile;
}

获取网络图片流

/**
 * 获取网络图片流
 *
 * @param url
 * @return
 */
public static InputStream getImageStream(String url) {
    try {
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        connection.setReadTimeout(5000);
        connection.setConnectTimeout(5000);
        connection.setRequestMethod("GET");
        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            InputStream inputStream = connection.getInputStream();
            return inputStream;
        }
    } catch (IOException e) {
        log.error("获取网络图片出现异常,图片路径为:" + url, e);
    }
    return null;
}

缩放图片

private static int scale(int w, int srcImgWidth) {

    return (w * srcImgWidth) / standardWidth;
}

 

ThumbnailsUtils 方式, 支持jpg, png 代码更整洁

maven 引入

<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>0.4.8</version>
</dependency>
public static void addImageWaterMark(File srcFile, BufferedImage waterMarkImgBuff, String formatName, int positionX,
                                     int positionY, int width, int height, String outPath) {

    OutputStream os = null;
    try {

        BufferedImage srcBuff = ImageIO.read(srcFile);

        int srcWidth = srcBuff.getWidth(null);
        int srcHeight = srcBuff.getHeight(null);

        Position position = new Coordinate(positionX, positionY);

        // 水印图片
        BufferedImage waterImage = Thumbnails.of(waterMarkImgBuff)
                .size(width, height)
                .outputQuality(1)
                .asBufferedImage();

        Thumbnails.Builder fullImageBuilder = Thumbnails.of(srcBuff)
                .size(srcWidth, srcHeight)
                .outputFormat(formatName)
                .watermark(position, waterImage, 1);

        BufferedImage fullImageBuff = null;
        if ("png".equalsIgnoreCase(formatName)) {
            fullImageBuff = fullImageBuilder.outputQuality(1).imageType(BufferedImage.TYPE_INT_ARGB).asBufferedImage();
        } else {
            fullImageBuff = fullImageBuilder.outputQuality(1).asBufferedImage();
        }

        // 生成图片
        os = new FileOutputStream(outPath);
        ImageIO.write(fullImageBuff, formatName, os);

    } catch (IOException e) {
        log.error("addImageWaterMark Exception", e);
    } finally {
        try {
            if (null != os) {
                os.close();
            }
        } catch (Exception e) {
            log.error("close Exception", e);
        }
    }
}
AnimatedGifUtils  处理 GIF 图片

maven 引入

<dependency>
    <groupId>com.madgag</groupId>
    <artifactId>animated-gif-lib</artifactId>
    <version>1.4</version>
</dependency>
public static void addImageWaterMark(File srcFile, BufferedImage waterMarkImgBuff, int positionX, int positionY, int width, int height, String outPath) {

    try {
        InputStream inputStream = new FileInputStream(srcFile.getAbsolutePath());
        GifDecoder decoder = new GifDecoder();
        //读入gif数据流
        decoder.read(inputStream);
        //读取帧数
        int frameCount = decoder.getFrameCount();
        AnimatedGifEncoder encoder = new AnimatedGifEncoder();
        encoder.start(outPath);
        encoder.setRepeat(0);
        Graphics2D g = null;
        /**
         * 对GIF进行拆分
         * 每一帧进行文字处理
         * 组装
         */
        for (int i = 0; i < frameCount; i++) {
            //初始化图像
            g = (Graphics2D) decoder.getFrame(i).getGraphics();
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(waterMarkImgBuff, positionX, positionY, width, height, null);

            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
            g.dispose();
            //组装每一帧
            encoder.addFrame(decoder.getFrame(i));
            //设置每帧的切换时间
            if (i != frameCount - 1) {
                encoder.setDelay(decoder.getDelay(i));
            }
        }
        encoder.finish();
    } catch (Exception e) {
        log.error("addImageWaterMark Exception", e);
    }
}

封装整合处理, 感觉有点丑, 后续再优化

public static File addImageWaterMark(File srcFile, File targetFile) {

    try {
        // 源图片 图片格式
        String formatName = FileType.getSuffixByFilename(srcFile.getName()).substring(1);
        Image srcImg = ImageIO.read(srcFile);
        int srcImgWidth = srcImg.getWidth(null); // 图片宽
        int srcImgHeight = srcImg.getHeight(null); // 图片高
        InputStream in = ImageUtils.getImageStream(waterMarkUrl);
        if (in == null) {
            log.warn("iconPath 获取网络图片失败: " + waterMarkUrl);
            return srcFile;
        }
        BufferedImage waterMarkImgBuff = ImageIO.read(in);
        // 计算水印图片的位置 图片的宽 高
        int margin = scale(10, srcImgWidth);
        int width = scale(waterMarkImgBuff.getWidth(), srcImgWidth);
        int height = scale(waterMarkImgBuff.getHeight(), srcImgWidth);
        int positionX = srcImgWidth - width - margin;
        int positionY = srcImgHeight - height - margin;

        if ("jpg".equalsIgnoreCase(formatName) || "png".equalsIgnoreCase(formatName)) {

            ThumbnailsUtils.addImageWaterMark(srcFile, waterMarkImgBuff, formatName, positionX, positionY,
                    width, height, targetFile.getAbsolutePath());
        } else if ("gif".equalsIgnoreCase(formatName)) {

            AnimatedGifUtils.addImageWaterMark(srcFile, waterMarkImgBuff, positionX, positionY,
                    width, height, targetFile.getAbsolutePath());
        }

    } catch (Exception e) {
        log.error("addImageWaterMark Exception", e);
    }
    return srcFile;
}

 

 

测试

public static void main(String[] args) {

    String fileImgPath1 = "D:\\temp\\" + 1 + ".jpg";
    String targetImgPath1 = "D:\\temp\\" + 1 + "-水印.jpg";
    addImageWaterMark(new File(fileImgPath1), new File(targetImgPath1));

    String fileImgPath2 = "D:\\temp\\" + 2 + ".jpg";
    String targetImgPath2 = "D:\\temp\\" + 2 + "-水印.jpg";
    addImageWaterMark(new File(fileImgPath2), new File(targetImgPath2));

    String fileImgPath3 = "D:\\temp\\" + 3 + ".png";
    String targetImgPath3 = "D:\\temp\\" + 3 + "-水印.png";
    addImageWaterMark(new File(fileImgPath3), new File(targetImgPath3));

    String fileImgPath4 = "D:\\temp\\" + 4 + ".png";
    String targetImgPath4 = "D:\\temp\\" + 4 + "-水印.png";
    addImageWaterMark(new File(fileImgPath4), new File(targetImgPath4));

    String fileImgPath5 = "D:\\temp\\" + 5 + ".gif";
    String targetImgPath5 = "D:\\temp\\" + 5 + "-水印.gif";
    addImageWaterMark(new File(fileImgPath5), new File(targetImgPath5));

    String fileImgPath6 = "D:\\temp\\" + 6 + ".gif";
    String targetImgPath6 = "D:\\temp\\" + 6 + "-水印.gif";
    addImageWaterMark(new File(fileImgPath6), new File(targetImgPath6));



}

效果图

 

 

 

 

收藏不点赞等于白嫖不付钱!!!

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!