首页 > 技术文章 > OSS 图片添加水印 image/watermark,image_

90s-ITBoy 2020-11-18 18:08 原文

需求:对已存在于OSS对象存储空间中的图片添加水印;

依赖:

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;



<!-- 主要依赖就是这个,具体代码请结合自己的开发和阿里云OSS接口更新进度情况 -->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.10.2</version>
</dependency> 
View Code

 

简单方式(公共读)的水印添加:

 

/**
     * @Author qtl
     * @Description 水印路径
     * @Date 15:29 2020/9/29
     * @Param [fileName]
     * @return java.lang.String
     **/
    public static String getWaterMarkUrl(String fileName){
        if (!StringUtils.isEmpty(fileName)) {
            FileNameMap fileNameMap = URLConnection.getFileNameMap();
            String contentTypeFor = fileNameMap.getContentTypeFor(fileName);
            String url = "";
            if (contentTypeFor != null) {// 图片
                int index = fileName.indexOf(".");
                String str = fileName.substring(index + 1);
                String newstr = str.toLowerCase();//使用toLowerCase()方法实现小写转换
//                String newstr2 = str.toUpperCase();//使用toUpperCase()方法实现大写转换
                if(!"gif".equalsIgnoreCase(newstr)){
                    url = "https://OSS对象空间名.oss-cn-hangzhou.aliyuncs.com/文件在OSS对象存储空间中所在目录/" + fileName + 
"?x-oss-process=image/watermark,image_d3NfZ2cvcGhvdG9BbmRWaWRlby8xNjA1MDc1OTE2OTIzLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSxQXzE1,t_100,g_se,x_5,y_5";
                }else{
                    url = "https://OSS对象空间名.oss-cn-hangzhou.aliyuncs.com/文件在OSS对象存储空间中所在目录/" + fileName; } 
          } 
       return url; 
      }else{ 
       return ""; 
     } 
}
View Code

 

解释:

  1. 传入参数是文件在OSS对象存储空间中的名称;
  2. 判断文件是否是图片;
  3. 判断是否是【gif】格式的图片,如果是的话就不加水印了,因为阿里云对于图片水印的处理是获取图片的第一帧进行加水印的,如果是gif的图片就会导致水印加成功了,而gif变成了静态图;
  4. 【url】路径拼接规则:从【https://】到【fileName】的配置就不多说了,代码里面有文字叙述,重点在【fileName】之后的代码,【+ "?x-oss-process=image/watermark,image_d3NfZ2cvcGhvdG9BbmRWaWRlby8xNjA1MDc1OTE2OTIzLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSxQXzE1,t_100,g_se,x_5,y_5"】这段代码就是水印的信息,主要是水印的路径和水印在图片中摆放的位置以及水印的大小、透明度等;
    1. 【?x-oss-process=image/watermark,image_】这段代码是指此样式是加水印的配置;
    2. 【d3NfZ2cvcGhvdG9BbmRWaWRlby8xNjA1MDc1OTE2OTIzLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSxQXzE1】这段代码是水印图片的路径、水印大小等信息,这个是经过base64处理过的字符串(阿里云官方推荐处理器网址:https://simplycalc.com/base64url-encode.php?spm=a2c4g.11186623.2.21.43eb26037IB7HM),未处理前的数据例子【文件在OSS对象存储空间中所在路径/水印文件全名?x-oss-process=image/resize,P_15】(P是指定水印图片按照主图的比例进行缩放,取值为缩放的百分比,一定要大写)经过base64处理后就如代码中的一串了;
    3. 【t_100,g_se,x_5,y_5】这段代码中【t】是代表不透明度,当为100时即为不透明,【g_se】是代表水印的在图片上的摆放方位为右下(共有9中,具体的请看下方提供的阿里云官方文档),【x_5,y_5】代表水印水平边距5、中线垂直偏移5;

更多的水印处理信息获取请查看阿里云官方文档: https://help.aliyun.com/document_detail/44957.html?spm=a2c4g.11186623.6.749.2e4e69danboaWz


复杂方式(私密读)的水印添加

// 方法名什么的就不写了,核心的代码就是这些
  // endpoint
    private static String endpoint="https://oss-cn-hangzhou.aliyuncs.com";
    // accessKey
    private static String accessKeyId="xxx";
    private static String accessKeySecret="xxx";
    // OSS对象存储空间名
    private static String bucketName="OSS对象空间名";
    // 文件存储目录
    private static String fileDir = "文件在OSS对象存储空间中所在目录";
    private OSSClient ossClient;

    public OSSUpload1() {
        ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
    }
   /**
     * @Author qtl
     * @Description 水印路径
     * @Date 15:29 2020/9/29
     * @Param [fileName]
     * @return java.lang.String
     **/
    public static String getWaterMarkUrl(String fileName){
        if (!StringUtils.isEmpty(fileName)) {
            String[] split = fileName.split("/");
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 组装样式代码
            String style = "image/watermark,image_d3NfZ2cvcGhvdG9BbmRWaWRlby8xNjAzODc0NjQxMDczLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSxQXzE1,t_100,P_10,g_nw,x_20,y_10";
            // 指定签名URL过期时间为10分钟。
            Date expiration = new Date(new Date().getTime() + 1000 * 60 * 60 * 24);
            GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, fileDir + split[split.length - 1], HttpMethod.GET);
            req.setExpiration(expiration);
            req.setProcess(style);
            URL signedUrl = ossClient.generatePresignedUrl(req);
            // 关闭OSSClient。
            ossClient.shutdown();
            return signedUrl.toString();
        }else{
            return "";
        }
    }
View Code

解释:

  1. 创建OSS链接;
  2. 组装样式代码,其中的难点就是【image/watermark,image_】后跟的经过base64处理后的水印图片信息;
  3. 私密读的数据访问链接肯定是要设定访问链接超时时间的;
  4. 创建OSS文件访问链接,需要将分别是【endpoint:OSS对象存储服务器所在区路径,这个路径可以在OSS服务器的控制台上找到】,【accessKeyId、accessKeySecret:是访问阿里云API 的密钥,尽量不要使用主密钥,创建一个 RAM 子账号并配上访问资源权限即可】;
  5. 将图片样式、超时时间追加到OSS文件访问链接上,然后调用OSS连接对象即可得到正确的加过水印的图片访问路径;
  6. 不要忘记关闭OSS链接!

 

总结(和获取缩略图的总结差不多):

  这两种方式的大概区别已经在上面简单的叙述过了,所以简单的讲一下这两种方式的利弊:

  • 第一种方式,简单便捷,但是因为是公共读的权限,因此对于保密性较高的数据不太友好,但是对于保密性不高的数据很好,因为这种请求连接是固定的,也就是说一个文件的访问链接在文件不移动的情况下是一直有效的,可以进行缓存;
  • 第二种,操作复杂,是私密读的权限,安全性较高,但是无法进行缓存操作,因为数据的每次请求都需要对请求连接追加超时时间的,即使是同一个文件的请求每次也都不同,因此有缓存需求的用这种方式行不通;
  • 在加水印时一定要判断是否是【gif】图片(注意:第二种水印添加代码中并未判断是否是gif图片);

 

推荐阅读