فهرست منبع

上传接口新增水印参数(腾讯云)

tsurumure 1 ماه پیش
والد
کامیت
ca1439a7be

+ 4 - 1
src/main/java/com/backendsys/modules/sdk/tencentcloud/cos/service/TencentCosService.java

@@ -16,7 +16,10 @@ import java.util.Map;
 public interface TencentCosService {
 
     // [腾讯云COS] 上传对象
-    SysFileResult putObject(MultipartFile multipartFile, String object_key) throws IOException;
+    SysFileResult putObject(MultipartFile multipartFile, String object_key, Integer is_watermark) throws IOException;
+    // [腾讯云COS] 打水印
+    void makeWater(String object_key);
+
     // [腾讯云COS] 删除对象
     void deleteObject(String object_key);
 

+ 79 - 9
src/main/java/com/backendsys/modules/sdk/tencentcloud/cos/service/impl/TencentCosServiceImpl.java

@@ -22,11 +22,15 @@ import com.qcloud.cos.exception.CosServiceException;
 import com.qcloud.cos.exception.MultiObjectDeleteException;
 import com.qcloud.cos.http.HttpMethodName;
 import com.qcloud.cos.model.*;
+import com.qcloud.cos.model.ciModel.common.ImageProcessRequest;
+import com.qcloud.cos.model.ciModel.persistence.CIUploadResult;
+import com.qcloud.cos.model.ciModel.persistence.PicOperations;
 import com.qcloud.cos.region.Region;
 import com.qcloud.cos.transfer.Transfer;
 import com.qcloud.cos.transfer.TransferManager;
 import com.qcloud.cos.transfer.TransferProgress;
 import com.qcloud.cos.transfer.Upload;
+import com.qcloud.cos.utils.Jackson;
 import org.joda.time.DateTime;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -36,10 +40,8 @@ import org.springframework.web.multipart.MultipartFile;
 import java.io.*;
 import java.math.BigDecimal;
 import java.net.URL;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
 import java.util.stream.Collectors;
 
 // 图片处理概述
@@ -121,7 +123,7 @@ public class TencentCosServiceImpl implements TencentCosService {
      * - 如果对象是图片,则同时产生缩略图
      */
     @Override
-    public SysFileResult putObject(MultipartFile multipartFile, String object_key) {
+    public SysFileResult putObject(MultipartFile multipartFile, String object_key, Integer is_watermark) {
 
         if (multipartFile.isEmpty()) throw new CustException("file 上传文件不能为空");
 
@@ -172,8 +174,9 @@ public class TencentCosServiceImpl implements TencentCosService {
             inputStream = multipartFile.getInputStream();
             PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, object_key, inputStream, metadata);
 
-            // 普通上传 (没有进度)
-//          //  cosClient.putObject(putObjectRequest);
+//            // 普通上传 (没有进度)
+//            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
+
 
             // 高级上传
             TransferManager transferManager = TencentCosUtil.createTransferManager(cosClient);
@@ -181,11 +184,18 @@ public class TencentCosServiceImpl implements TencentCosService {
             showTransferProgress(filename, upload, null);    // 查询上传进度,直到上传结束
             UploadResult uploadResult = upload.waitForUploadResult();   // 捕获可能出现的异常
 
+            System.out.println("[腾讯云][cos-uploadResult] = " + uploadResult.getDateStr());
+
+            // 打水印
+            if (is_watermark != null && is_watermark == 1) {
+                makeWater(object_key);
+            }
+
             // 自定义返回结果实体
             SysFileResult result = new SysFileResult();
             result.setKey(object_key);
-            result.setRequest_id(uploadResult.getRequestId());
-            result.setE_tag(uploadResult.getETag());
+//            result.setRequest_id(uploadResult.getRequestId());
+//            result.setE_tag(uploadResult.getETag());
             result.setDomain(ACCESSIBLE_DOMAIN);
             result.setUrl(ACCESSIBLE_DOMAIN + "/" + object_key);
             result.setTarget(1);
@@ -208,6 +218,66 @@ public class TencentCosServiceImpl implements TencentCosService {
 
     }
 
+    // [腾讯云COS] 打水印
+    public void makeWater(String object_key) {
+        // 初始化 CosClient
+        COSClient cosClient = getClient();
+        InputStream inputStream = null;
+        try {
+
+            // 对原图发起云上处理
+            ImageProcessRequest request = new ImageProcessRequest(BUCKET_NAME, object_key);
+
+            PicOperations picOperations = new PicOperations();
+            picOperations.setIsPicInfo(1);
+            List<PicOperations.Rule> rule_list = new ArrayList<>();
+
+            PicOperations.Rule rule_item = new PicOperations.Rule();
+
+            // -- 水印 --------------------------------
+            // 文字水印:https://cloud.tencent.com/document/product/436/119425
+            // 上传时处理:https://cloud.tencent.com/document/product/460/18147#.E4.BA.91.E4.B8.8A.E6.95.B0.E6.8D.AE.E5.A4.84.E7.90.86
+            String text = "稻谷文化";
+            byte[] textBates = text.getBytes(StandardCharsets.UTF_8);
+            String encodedText = Base64.getUrlEncoder().encodeToString(textBates).replaceAll("=", "");
+            String rule = "watermark/2/text/" + encodedText +
+                    "/fill/IzNEM0QzRA/fontsize/28/dissolve/50/batch/1/spacing/40/degree/35";
+            // - dissolve: 文字透明度,取值1 - 100 ,默认90
+            // - gravity: 九宫格位置 (gravity/northeast/)
+            // - dx: 水平(横轴)边距,单位为像素,缺省值为0
+            // - dy: 垂直(纵轴)边距,单位为像素,默认值为0
+            // - batch: 平铺水印功能,可将文字水印平铺至整张图片。值为1时,表示开启平铺水印功能
+            // - spacing: 平铺模式下的水平、垂直间距相对文字水印贴图的宽高百分比,范围为[0,100],默认10
+            // - degree: 文字水印的旋转角度设置,取值范围为0 - 360,默认0
+
+
+            rule_item.setBucket(BUCKET_NAME);
+            rule_item.setFileId("/" + object_key);  // 以 '/' 开头是为绝对路径,否则会在当前目录下再创建一个对象路径
+            rule_item.setRule(rule);
+            // ----------------------------------
+
+            rule_list.add(rule_item);
+            picOperations.setRules(rule_list);
+
+            System.out.println("Jackson.toJsonString(picOperations) = " + Jackson.toJsonString(picOperations));
+
+            request.setPicOperations(picOperations);
+            CIUploadResult ciUploadResult = cosClient.processImage(request);
+            System.out.println("[腾讯云][cos-ciUploadResult] OriginalInfo= " + Jackson.toJsonString(ciUploadResult.getOriginalInfo()));
+            System.out.println("[腾讯云][cos-ciUploadResult] ProcessResults = " + Jackson.toJsonString(ciUploadResult.getProcessResults()));
+
+        } finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (IOException e) {
+                    // 忽略关闭流时的异常
+                }
+            }
+            if (cosClient != null) cosClient.shutdown();
+        }
+    }
+
     // [腾讯云COS] 查询对象是否存在
     @Override
     public boolean doesObjectExist(String object_key) {

+ 151 - 0
src/main/java/com/backendsys/modules/sdk/tencentcloud/cos/utils/WaterMarkUtil.java

@@ -0,0 +1,151 @@
+//package com.backendsys.modules.sdk.tencentcloud.cos.utils;
+//
+//import javax.imageio.ImageIO;
+//import java.awt.*;
+//import java.awt.image.BufferedImage;
+//import java.io.File;
+//import java.io.FileOutputStream;
+//import java.io.InputStream;
+//import java.io.OutputStream;
+//
+///**
+// * springboot进行图片上传和添加水印
+// * https://cloud.tencent.com/developer/article/2074668
+// */
+//public class WaterMarkUtil {
+//    // 水印透明度
+//    private static float alpha = 0.3f;
+//    // 水印横向位置
+//    private static int positionWidth = 50;
+//    // 水印纵向位置
+//    private static int positionHeight = 100;
+//    // 水印文字字体
+//    private static Font font = new Font("宋体", Font.BOLD, 60);
+//    // 水印文字颜色
+//    private static Color color = Color.red;
+//
+//    /**
+//     * 给图片添加水印文字
+//     *
+//     * @param text       水印文字
+//     * @param srcImgPath 源图片路径
+//     * @param targetPath 目标图片路径
+//     */
+//    public static void markImage(String text, String srcImgPath, String targetPath) {
+//        markImage(text, srcImgPath, targetPath, null);
+//    }
+//
+//    /**
+//     * 给图片添加水印文字、可设置水印文字的旋转角度
+//     *
+//     * @param text 水印文字
+//     * @param srcImgPath 源图片路径
+//     * @param targetPath 目标图片路径
+//     * @param degree 水印旋转
+//     */
+//    public static void markImage(String text, String srcImgPath, String targetPath, Integer degree) {
+//
+//        OutputStream os = null;
+//        try {
+//            // 0、图片类型
+//            String type = srcImgPath.substring(srcImgPath.indexOf(".") + 1, srcImgPath.length());
+//
+//            // 1、源图片
+//            Image srcImg = ImageIO.read(new File(srcImgPath));
+//
+//            int imgWidth = srcImg.getWidth(null);
+//            int imgHeight = srcImg.getHeight(null);
+//
+//            BufferedImage buffImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
+//
+//            // 2、得到画笔对象
+//            Graphics2D g = buffImg.createGraphics();
+//            // 3、设置对线段的锯齿状边缘处理
+//            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+//            g.drawImage(srcImg.getScaledInstance(imgWidth, imgHeight, 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、设置水印文字Font
+//            g.setFont(font);
+//            // 7、设置水印文字透明度
+//            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
+//            // 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
+//
+//            //设置水印的坐标
+//            int x = imgWidth - 2*getWatermarkLength(text, g);
+//            int y = imgHeight - 2*getWatermarkLength(text, g);
+//            g.drawString(text, x, y);  //画出水印
+////            g.drawString(text, positionWidth, positionHeight);
+//            // 9、释放资源
+//            g.dispose();
+//            // 10、生成图片
+//            os = new FileOutputStream(targetPath);
+//            // ImageIO.write(buffImg, "JPG", os);
+//            ImageIO.write(buffImg, type.toUpperCase(), os);
+//
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        } finally {
+//            try {
+//                if (null != os)
+//                    os.close();
+//            } catch (Exception e) {
+//                e.printStackTrace();
+//            }
+//        }
+//    }
+//
+//    /**
+//     * 给图片添加水印文字、可设置水印文字的旋转角度
+//     * @param text 水印文字
+//     * @param inputStream 源图片路径
+//     * @param outputStream 目标图片路径
+//     * @param degree 水印旋转
+//     * @param typeName
+//     */
+//    public static void markImageByIO(String text, InputStream inputStream, OutputStream outputStream,
+//                                     Integer degree, String typeName) {
+//        try {
+//            // 1、源图片
+//            Image srcImg = ImageIO.read(inputStream);
+//
+//            int imgWidth = srcImg.getWidth(null);
+//            int imgHeight = srcImg.getHeight(null);
+//            BufferedImage buffImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
+//
+//            // 2、得到画笔对象
+//            Graphics2D g = buffImg.createGraphics();
+//            // 3、设置对线段的锯齿状边缘处理
+//            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+//            g.drawImage(srcImg.getScaledInstance(imgWidth, imgHeight, 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、设置水印文字Font
+//            g.setFont(font);
+//            // 7、设置水印文字透明度
+//            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
+//            // 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
+//
+//            g.drawString(text, positionWidth, positionHeight);
+//            // 9、释放资源
+//            g.dispose();
+//            // 10、生成图片
+//            ImageIO.write(buffImg, typeName.toUpperCase(), outputStream);
+//
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//    }
+//
+//    public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
+//        return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
+//    }
+//}

+ 2 - 2
src/main/java/com/backendsys/modules/upload/controller/SysFileController.java

@@ -66,8 +66,8 @@ public class SysFileController {
     @Operation(summary = "上传文件 (普通上传,单文件上传不超过 100MB)")
     @PreAuthorize("@sr.hasPermission('1.1.3')")
     @PostMapping("/api/upload/uploadSmall")
-    public Result uploadSmall(@RequestParam("file") MultipartFile multipartFile, Long category_id) {
-        return Result.success().put("data", sysFileService.uploadSmall(multipartFile, category_id));
+    public Result uploadSmall(@RequestParam("file") MultipartFile multipartFile, Long category_id, Integer is_watermark) {
+        return Result.success().put("data", sysFileService.uploadSmall(multipartFile, category_id, is_watermark));
     }
 
     @SysLog("编辑文件")

+ 1 - 1
src/main/java/com/backendsys/modules/upload/service/SysFileService.java

@@ -18,7 +18,7 @@ public interface SysFileService extends IService<SysFile> {
     Map<String, Object> selectUploadTarget();
 
     // 上传文件 (单文件大小不超过 n)
-    SysFile uploadSmall(MultipartFile file, Long category_id);
+    SysFile uploadSmall(MultipartFile file, Long category_id, Integer is_watermark);
 
     // 删除文件
     Map<String, Object> removeUploadFile(SysFile sysFile, SysFile querySysFile);

+ 5 - 6
src/main/java/com/backendsys/modules/upload/service/impl/SysFileServiceImpl.java

@@ -88,7 +88,6 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileDao, SysFile> impleme
                     // 腾讯云 (color值通过base64加密, #f8f8f8)
                     if (sysFile.getTarget() == 1) {
                         backgroundColor = "#" + backgroundColor;
-                        System.out.println("base64 encode: " + Base64.encode(backgroundColor));
                         sysFile.setUrl_thumb(sysFile.getUrl() + "?imageMogr2/thumbnail/" + width + "x" + height + "/pad/1/color/" + Base64.encode(backgroundColor));
                     }
                     // 抖音云
@@ -142,7 +141,7 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileDao, SysFile> impleme
     }
 
     // [方法] 上传事件
-    private SysFile uploadEvent(MultipartFile multipartFile, Long category_id, Integer target) {
+    private SysFile uploadEvent(MultipartFile multipartFile, Long category_id, Integer is_watermark, Integer target) {
         try {
 
             String filename = multipartFile.getOriginalFilename();
@@ -156,7 +155,7 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileDao, SysFile> impleme
             }
             if (target == 1) {
                 // [腾讯云-上传对象]
-                uploadResult = tencentCosService.putObject(multipartFile, null);
+                uploadResult = tencentCosService.putObject(multipartFile, null, is_watermark);
             }
             if (target == 3) {
                 // [抖音云-上传对象]
@@ -242,7 +241,7 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileDao, SysFile> impleme
      * - target: 上传目标 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)
      */
     @Override
-    public SysFile uploadSmall(MultipartFile multipartFile, Long category_id) {
+    public SysFile uploadSmall(MultipartFile multipartFile, Long category_id, Integer is_watermark) {
 
         List<SysCommon> sysCommonList = sysCommonService.getCommonByCategory("UPLOAD");
 
@@ -303,7 +302,7 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileDao, SysFile> impleme
                     sysFileDao.updateById(sysFileEntity);
                 } else {
                     // [DB] 创建新的文件
-                    sysFileEntity = uploadEvent(multipartFile, category_id, UPLOAD_TARGET.get());
+                    sysFileEntity = uploadEvent(multipartFile, category_id, is_watermark, UPLOAD_TARGET.get());
                     // [格式化] 封面 (图片类型)
                     sysFileEntity = setThumbUrl(sysFileEntity, UPLOAD_THUMB_SIZE.get(), UPLOAD_THUMB_SIZE.get(), StyleEnums.THUMB_BACKGROUND.getValue());
                 }
@@ -312,7 +311,7 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileDao, SysFile> impleme
             } else {
                 // 不开启 MD5秒 传,则直接初始化分块
                 // [方法] 上传事件
-                sysFileEntity = uploadEvent(multipartFile, category_id, UPLOAD_TARGET.get());
+                sysFileEntity = uploadEvent(multipartFile, category_id, is_watermark, UPLOAD_TARGET.get());
                 // [格式化] 封面 (图片类型)
                 sysFileEntity = setThumbUrl(sysFileEntity, UPLOAD_THUMB_SIZE.get(), UPLOAD_THUMB_SIZE.get(), StyleEnums.THUMB_BACKGROUND.getValue());
                 return sysFileEntity;