首页 > 编程语言 >Java中使用Graphics2D实现图片添加文字/图片水印

Java中使用Graphics2D实现图片添加文字/图片水印

时间:2024-02-27 15:22:40浏览次数:27  
标签:Graphics2D Java java image 水印 import new 图片

场景

java实现给图片添加水印实现步骤:

获取原图片对象信息(本地图片或网络图片)

添加水印(设置水印颜色、字体、坐标等)

处理输出目标图片。

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi

实现

1、新建工具类

 

import org.apache.commons.lang3.StringUtils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 添加水印util
 */
public class WatermarkUtils {

    /**
     * 读取本地图片
     *
     * @param path 本地图片存放路径
     */
    public static Image readLocalPicture(String path) {
        if (null == path) {
            throw new RuntimeException("本地图片路径不能为空");
        }
        // 读取原图片信息 得到文件
        File srcImgFile = new File(path);
        try {
            // 将文件对象转化为图片对象
            return ImageIO.read(srcImgFile);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 读取网络图片
     *
     * @param path 网络图片地址
     */
    public static Image readNetworkPicture(String path) {
        if (null == path) {
            throw new RuntimeException("网络图片路径不能为空");
        }
        try {
            // 创建一个URL对象,获取网络图片的地址信息
            URL url = new URL(path);
            // 将URL对象输入流转化为图片对象 (url.openStream()方法,获得一个输入流)
            BufferedImage bugImg = ImageIO.read(url.openStream());
            if (null == bugImg) {
                throw new RuntimeException("网络图片地址不正确");
            }
            return bugImg;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 水印处理
     *
     * @param image     图片对象
     * @param type      水印类型(1-文字水印 2-图片水印)
     * @param watermark 水印内容(文字水印内容/图片水印的存放路径)
     * @param tarImgPath 输出照片的存放路径
     * @param x 水印坐标x
     * @param y 水印坐标y
     */
    public static String manageWatermark(Image image, Integer type, String watermark,int x ,int y,String tarImgPath) {
        int imgWidth = image.getWidth(null);
        int imgHeight = image.getHeight(null);
        BufferedImage bufImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
        // 加水印:
        // 创建画笔
        Graphics2D graphics = bufImg.createGraphics();
        // 绘制原始图片
        graphics.drawImage(image, 0, 0, imgWidth, imgHeight, null);
        // 校验水印的类型
        if (type == 1) {
            if (StringUtils.isEmpty(watermark)) {
                throw new RuntimeException("文字水印内容不能为空");
            }
            // 添加文字水印:
            // 根据图片的背景设置水印颜色
            graphics.setColor(new Color(255, 0, 0, 128));
            // 设置字体  画笔字体样式为微软雅黑,加粗,文字大小为45pt
            graphics.setFont(new Font("微软雅黑", Font.BOLD, 45));
            // 画出水印 第一个参数是水印内容,第二个参数是x轴坐标,第三个参数是y轴坐标
            graphics.drawString(watermark, x, y);
            graphics.dispose();
        } else {
            // 添加图片水印:
            if (StringUtils.isEmpty(watermark)) {
                throw new RuntimeException("图片水印存放路径不能为空");
            }
            Image srcWatermark = readLocalPicture(watermark);
            //获取图片原始宽度
            //int watermarkWidth = srcWatermark.getWidth(null);
            int watermarkWidth = 50;
            //获取图片原始高度
            //int watermarkHeight = srcWatermark.getHeight(null);
            int watermarkHeight = 50;
            // 设置 alpha 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
            graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.9f));
            // 绘制水印图片
            graphics.drawImage(srcWatermark, x, y, watermarkWidth, watermarkHeight, null);
            graphics.dispose();
        }
        // 输出图片
        try {
            FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
            ImageIO.write(bufImg, "png", outImgStream);
            outImgStream.flush();
            outImgStream.close();
            return "水印添加成功";
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

2、编写测试

测试本地图片添加文字水印

        Image image = readLocalPicture("D://test//test.png");
        //添加文字水印
        manageWatermark(image,1,"霸道的程序猿",150,50,"D://test//testResult"+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))+".png");

其中水印位置的确定是根据像素坐标来的,可使用画图工具打开照片,确定像素坐标

 

右下角有输出的像素坐标。

添加文字水印效果

 

测试添加图片水印

        Image image = readLocalPicture("D://test//test.png");
        //添加图片水印
        manageWatermark(image,2,"D://test//mark.jpg",150,50,"D://test//testResult"+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))+".png");

测试效果

 

标签:Graphics2D,Java,java,image,水印,import,new,图片
From: https://www.cnblogs.com/badaoliumangqizhi/p/18036947

相关文章

  • Java 中 MessageFormat.format 用法
    转载自:https://blog.csdn.net/xiaokui_wingfly/article/details/46124057 查看原文:http://www.ibloger.net/article/139.htmlMessageFormat本身与语言环境无关,而与用户提供给MessageFormat的模式和用于已插入参数的子格式模式有关,以生成适用于不同语言环境的消息。Mes......
  • java 通过 microsoft graph 调用outlook
    废话不多说一官方文档先看一下官方文档,https://learn.microsoft.com/zh-cn/graph/tutorials/java?context=outlook%2Fcontext&tabs=aad&tutorial-step=1其中的代码,可以通过地址下载:https://developer.microsoft.com/en-us/graph/quick-start 二授权方式microsoft登录授权......
  • Java面向对象之接口和抽象类的区别一目了然
    介绍相信对于Java面向对象部分,很多人很长一段时间对于接口和抽象类的区别,使用场景都不是很熟悉,同是作为抽象层重要的对象,工作中到底什么情况下使用抽象类,不是很清楚。本文就一次性把这些概念一次性说清楚,不用再烦恼了,哈哈!核心概念接口与抽象类最明显的区别可能就是使用上的......
  • java读取resource下的文件 下载
    点击查看代码publicvoiddownloadKsxxYzyTemplate(HttpServletRequestrequest,HttpServletResponseresponse){try{//FileDownloadUtils.downloadFileFromResource(response,YZYMB_NAME,YZYMB_URL);FileDownloadUtils.downloadFileFro......
  • C#与Java的继承与实现上的差异
    虽然C#和Java都支持继承和接口实现这两种面向对象编程的基本概念,但它们在一些细节上有一些差异。继承(Inheritance)单继承vs多继承:C#支持单继承,一个类只能直接继承自一个父类。Java也支持单继承,一个类只能直接继承自一个父类。基类构造函数的调用:在C#中,如果......
  • 【13.0】JavaScript之流程控制
    【一】if判断【1】语法//if-elseif(条件){条件成立执行的代码块}else{条件不成立时执行的代码块}//if-elseif-elseif(条件){条件成立执行的代码块}elseif(条件){条件成立执行的代码块}else{条件不成立时执行的代码块}//()条件{}执行的代码块【2】if~e......
  • 【16.0】JavaScript之对象
    【一】对象js中的对象是无序的属性集合我们可以把js中的对象想象成键值对,其中值可以是数据或者函数特征-在对象中属性表示行为-在对象中用方法表示可以看成Python中的字典,但是在JS中的自定义对象要比Python里面的字典操作起来更方便【二】对象创建【1】对象字面量(Objec......
  • 【15.0】JavaScript之函数
    【一】函数函数function,也叫做功能,方法,函数可以将一段代码封装起来,函数就具备了特定的功能函数的作用就是封装一段代码,将来可以重复使用在Python中定义函数需要用def在JavaScript中定义函数需要用function【二】函数声明【1】先声明再调用函数必须先声明,才能......
  • 【14.0】JavaScript之数组
    【一】什么是数组数组是一组有序的数据集合,数组内部可以存放多个数据,不限制数据类型,数组的长度可以动态调整数组类似于Python当中的列表【二】创建数组创建数据的最简单方式是通过字面量vararr=[]也可以通过数组对象去创建vararr=newArray()存放多个......
  • 【18.0】JavaScript之JS事件案例
    【一】开关灯示例<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title><style>.c1{height:400px;width:40......