• springboot 做图片添加水印(图片来源:网络或者本地 水印条数:多条)


    和前面的几个随笔一样,都是在一个大型项目里面。今天要做的是证书生成下载。在图片上面添加水印,水印条数多条。直接代码 ——>

    介绍:

    1.我这里面是用的一个工具类,当然里面我自己又添加一些代码比如,我这里面的图片是自己先上传到文件服务器,然后服务器返回给我一个url ,这个url在浏览器里面就可以直接下载。

    所以我这里获取图片的地方改动了一下。

    2.原本这里面是只能添加一条水印的,然后我就对它进行了修改。直接说就是,你要添加几条水印,就是工具类参数那边的改动就是了。

    3.添加完成的水印,原本是保存在本地的,然后我这边还是要上传到服务器,也就是说添加水印的过程是在服务器进行完成。这里我对工具类进行了修改,文件以流的方式上传而不经本地。

    4.就是因为第三步,所以原本水印的文字是用的windows下面的自带字体,但是添加水印的过程是在服务器,而服务器并没下载字体。解决方法两个   一个是服务器下载需要的字体,第二种就是我这种把需要的字体放在项目根目录,然后读取字体文件。因为项目部署是打成jar包目录读取又不同,所以我这处理了一下。

    字体放置位置:

    service层接口:

    /**
         * 证书需要的字段
         * @return
         */
        Map<String,Object> getAllStaffTrainWorker(JSONObject jsonParam);
    

    serviceImpl实现类:

      1 /**
      2      * 获取证书需要的字段
      3      * @return
      4      */
      5     @Override
      6     public Map<String,Object> getAllStaffTrainWorker(JSONObject jsonParam) {
      7         String allStaffWorkerId = jsonParam.getString("allStaffWorkerIds");
      8         if (null == allStaffWorkerId){
      9             errLog("getAllStaffTrainWorker", ErrorCodeMsg.PARAM_ERROR.getMessage(), "员工id不存在");
     10             throw new AttemptException(ErrorCodeMsg.PARAM_ERROR,"员工id不存在");
     11         }
     12         //员工表查询出员工的基本信息
     13         Example example = new Example(AllStaffTrainWorker.class);
     14         Example.Criteria criteria = example.createCriteria();
     15         criteria.andEqualTo("isDeleted", CmnConstants.IS_DELETED_NO);
     16         criteria.andEqualTo("isEnabled", CmnConstants.IS_ENABLED_YES);
     17         String [] allStaffWorkerArry = allStaffWorkerId.split(",");
     18         List<Long> allStaffWorkerIds = new ArrayList<>();
     19         for (String allStaffWorkerIdss :allStaffWorkerArry){
     20             allStaffWorkerIds.add(Long.valueOf(allStaffWorkerIdss));
     21         }
     22         criteria.andIn("allStaffWorkerId",allStaffWorkerIds);
     23         List<AllStaffTrainWorker> allStaffTrainWorkerList = this.allStaffTrainWorkerMapper.selectByExample(example);
     24         //姓名
     25         String workerName = null;
     26         //身份证号
     27         String workerCardNum = null;
     28         //组织名称
     29         String allStaffOrgName = null;
     30         //学员得分
     31         BigDecimal studentScore = null;
     32         //证书编号
     33         String certNum = null;
     34         //证书名称
     35         String trainCredentialName = null;
     36         //获取模板内容
     37         String templateContent = null;
     38         //获取背景图片路径
     39         String imgUrl =null;
     40         if (null != allStaffTrainWorkerList){
     41             for (AllStaffTrainWorker allStaffTrainWorker1 : allStaffTrainWorkerList){
     42                 workerName= allStaffTrainWorker1.getWorkerName();
     43                 workerCardNum = allStaffTrainWorker1.getWorkerCardNum();
     44                 allStaffOrgName = allStaffTrainWorker1.getAllStaffOrgName();
     45             }
     46             //考试表获取分数
     47             Example example1 = new Example(AllStaffTrainWorkerExam.class);
     48             Example.Criteria criteria1 = example1.createCriteria();
     49             criteria1.andEqualTo("isDeleted", CmnConstants.IS_DELETED_NO);
     50             criteria1.andEqualTo("isEnabled", CmnConstants.IS_ENABLED_YES);
     51             criteria1.andEqualTo("allStaffWorkerId",allStaffWorkerId);
     52             List<AllStaffTrainWorkerExam> allStaffTrainWorkerExamList = this.allStaffTrainWorkerExamMapper.selectByExample(example1);
     53             for (AllStaffTrainWorkerExam allStaffTrainWorkerExam : allStaffTrainWorkerExamList){
     54                 studentScore =  allStaffTrainWorkerExam.getStudentScore();
     55             }
     56             //证书表得到证书编号
     57             Example example2 = new Example(AllStaffTrainWorkerCert.class);
     58             Example.Criteria criteria2 = example2.createCriteria();
     59             criteria2.andEqualTo("isDeleted", CmnConstants.IS_DELETED_NO);
     60             criteria2.andEqualTo("isEnabled", CmnConstants.IS_ENABLED_YES);
     61             criteria2.andEqualTo("allStaffWorkerId",allStaffWorkerId);
     62             List<AllStaffTrainWorkerCert> allStaffTrainWorkerCertList = this.allStaffTrainWorkerCertMapper.selectByExample(example2);
     63             Long allStaffTrainCertId = null;
     64             for (AllStaffTrainWorkerCert allStaffTrainWorkerCert : allStaffTrainWorkerCertList){
     65                 certNum =  allStaffTrainWorkerCert.getCertNum();
     66                 allStaffTrainCertId = allStaffTrainWorkerCert.getAllStaffTrainCertId();
     67             }
     68             //配置证书表获取证书名称
     69             Example example3= new Example(AllStaffTrainCert.class);
     70             Example.Criteria criteria3 = example3.createCriteria();
     71             criteria3.andEqualTo("isDeleted", CmnConstants.IS_DELETED_NO);
     72             criteria3.andEqualTo("isEnabled", CmnConstants.IS_ENABLED_YES);
     73             criteria3.andEqualTo("allStaffTrainCertId",allStaffTrainCertId);
     74             List<AllStaffTrainCert> allStaffTrainCertList = this.allStaffTrainCertMapper.selectByExample(example3);
     75             //模板id
     76             Long allStaffTrainTemplateId = null;
     77             //图片id
     78             Long allStaffTrainImgId = null;
     79             for (AllStaffTrainCert allStaffTrainCert : allStaffTrainCertList){
     80                 trainCredentialName = allStaffTrainCert.getTrainCredentialName();
     81                 allStaffTrainTemplateId = allStaffTrainCert.getAllStaffTrainTemplateId();
     82                 allStaffTrainImgId = allStaffTrainCert.getAllStaffTrainImgId();
     83             }
     84             Example example4 = new Example(AllStaffTrainCertTemplate.class);
     85             Example.Criteria criteria4 = example4.createCriteria();
     86             criteria4.andEqualTo("isDeleted", CmnConstants.IS_DELETED_NO);
     87             criteria4.andEqualTo("isEnabled", CmnConstants.IS_ENABLED_YES);
     88             criteria4.andEqualTo("allStaffTrainTemplateId",allStaffTrainTemplateId);
     89             AllStaffTrainCertTemplate allStaffTrainCertTemplate = this.allStaffTrainCertTemplateMapper.selectOneByExample(example4);
     90             //获取模板内容
     91              templateContent = allStaffTrainCertTemplate.getTemplateContent();
     92             Example example5 = new Example(AllStaffTrainCertImg.class);
     93             Example.Criteria criteria5 = example5.createCriteria();
     94             criteria5.andEqualTo("isDeleted", CmnConstants.IS_DELETED_NO);
     95             criteria5.andEqualTo("isEnabled", CmnConstants.IS_ENABLED_YES);
     96             criteria5.andEqualTo("allStaffTrainImgId",allStaffTrainImgId);
     97             AllStaffTrainCertImg allStaffTrainCertImg = this.allStaffTrainCertImgMapper.selectOneByExample(example5);
     98             //获取背景图片路径
     99              imgUrl = allStaffTrainCertImg.getImgUrl();
    100         }
    101         ClassPathResource classPathResource = new ClassPathResource("fonts/msyh.ttc");
    102         InputStream inputStream = null;
    103         try {
    104            inputStream = classPathResource.getInputStream();
    105         }catch (Exception e){
    106             e.getMessage();
    107         }
    108         Font dynamicFont = null;
    109         try {
    110             dynamicFont = Font.createFont(Font.TRUETYPE_FONT, inputStream);
    111         }catch (Exception e){
    112             e.printStackTrace();
    113         }
    114         Font font = dynamicFont.deriveFont(Font.PLAIN, 28); //水印字体 方法3
    115         //水印字体
    116         /*Font font = new Font("微软雅黑", Font.PLAIN, 28);*/
    117         //源图片地址
    118         String srcImgPath="http://"+imgUrl;
    119         //待存储的地址
    120         String tarImgPath = "F:/证书.jpeg";
    121         //格式化时间
    122         SimpleDateFormat f=new SimpleDateFormat("yyyy     MM     dd");
    123         String format = f.format(new Date());
    124         //时间
    125         String waterMarkContent=format;
    126         //姓名
    127         String workerNames = workerName;
    128         //身份证号
    129         String workerCardNums = workerCardNum;
    130         //组织名称
    131         String allStaffOrgNames = allStaffOrgName;
    132         //学员得分
    133         BigDecimal studentScores = studentScore;
    134         //证书编号
    135         String certNums =certNum;
    136         //证书名称
    137         String trainCredentialNames = trainCredentialName;
    138         //获取模板内容
    139         String templateContents = templateContent;
    140 
    141         //水印图片色彩以及透明度
    142         Color color=new Color(79 ,79 ,79);
    143         BufferedImage bufferedImage = (BufferedImage) WaterMarkUtils.addWaterMark(srcImgPath, tarImgPath, waterMarkContent, workerNames, workerCardNums, allStaffOrgNames, studentScores, certNums, trainCredentialNames, templateContents, color, font);
    144         String sessionToke =jsonParam.getString("sessionToke");
    145         String attname = "证书"+".jpeg";
    146         String url = null;
    147         try {
    148             byte[] jpegs = imageToBytes(bufferedImage, "jpeg");
    149             url = FastDFSUtils.getDoUpload(sessionToke,attname,jpegs);
    150         }catch (Exception e){
    151             errLog("getDownloadAllStaffWorkers",ErrorCodeMsg.UNKNOWN_ERROR.getMessage(),e.getMessage());
    152             throw new AttemptException(ErrorCodeMsg.UNKNOWN_ERROR,e.getMessage());
    153         }
    154         Map<String, Object> resultMap = getFastDFSFileInfoMap(url,attname);
    155         return resultMap;
    156     }
    157 
    158 public  byte[] imageToBytes(BufferedImage bImage, String format) {
    159     ByteArrayOutputStream out = new ByteArrayOutputStream();
    160     try {
    161         ImageIO.write(bImage, format, out);
    162     } catch (IOException e) {
    163         e.printStackTrace();
    164     }
    165     return out.toByteArray();
    166 }
    167 
    168 /**
    169  * 返回给前端下载地址
    170  *
    171  * @param url
    172  * @param attname
    173  * @return
    174  */
    175 private Map<String, Object> getFastDFSFileInfoMap(String url, String attname) {
    176     String filePath = null;
    177     if (StringUtils.isNotEmpty(url)) {
    178         JSONObject jsonObject = JSONObject.parseObject(url);
    179         String data = jsonObject.getString("data");
    180         JSONObject dataObject = JSONObject.parseObject(data);
    181         filePath = dataObject.getString("filePath");
    182         if (StringUtils.isEmpty(filePath)) {
    183             errLog("getFastDFSFileInfoMap", ErrorCodeMsg.UNKNOWN_ERROR.getMessage(), "获取文件服务下载地址为空");
    184             throw new AttemptException(ErrorCodeMsg.UNKNOWN_ERROR, "获取文件服务下载地址为空");
    185         }
    186     }
    187     Map<String, Object> map = new HashMap<>(32);
    188     map.put("url",fileServer+"/"+filePath);
    189     map.put("attname", attname);
    190     return map;
    191 }

    controller层代码:

    1 /**
    2      * 证书需要的内容
    3      * @return
    4      */
    5     @PostMapping("/getAllStaffTrainWorker")
    6     public ResponseStruct getAllStaffTrainWorker(@RequestBody JSONObject jsonParam){
    7         return ResponseStruct.success(this.allStaffTrainWorkerCertInterface.getAllStaffTrainWorker(jsonParam));
    8     }

    图片处理工具类 WaterMarkUtils:

      1 package com.guangl.allStaff.train.utils;
      2 
      3 
      4 import javax.imageio.ImageIO;
      5 import java.awt.*;
      6 import java.awt.image.BufferedImage;
      7 import java.io.*;
      8 import java.math.BigDecimal;
      9 import java.net.HttpURLConnection;
     10 import java.net.URL;
     11 
     12 public class WaterMarkUtils {
     13     /**
     14      * @param srcImgPath 源图片路径
     15      * @param tarImgPath 保存的图片路径
     16      * @param waterMarkContent 水印内容
     17      * @param markContentColor 水印颜色
     18      * @param font 水印字体
     19      * @param workerNames
     20      */
     21     public static Object addWaterMark(String srcImgPath, String tarImgPath, String waterMarkContent, String workerNames,
     22                                       String workerCardNums, String allStaffOrgNames, BigDecimal studentScores, String certNums, String trainCredentialNames,
     23                                       String templateContents, Color markContentColor, Font font) {
     24         try {
     25             //new一个url对象
     26             URL url = new URL(srcImgPath);
     27             //打开链接
     28             HttpURLConnection  conn = (HttpURLConnection)url.openConnection();
     29             //设置请求方式
     30             /*conn.setRequestMethod("GET");*/
     31             //超时相应时间为5秒
     32             conn.setConnectTimeout(5*1000);
     33             //通过输入流获取图片数据
     34             InputStream inputStream = null;
     35             try {
     36                 inputStream = conn.getInputStream();
     37             }catch (Exception e){
     38                 e.printStackTrace();
     39             }
     40             //文件转化为图片
     41             Image srcImg = null;
     42             try {
     43                 srcImg = ImageIO.read(inputStream);
     44             }catch (Exception e){
     45                 e.printStackTrace();
     46             }
     47             //获取图片的宽
     48             int srcImgWidth = srcImg.getWidth(null);
     49             //获取图片的高
     50             int srcImgHeight = srcImg.getHeight(null);
     51 
     52             // 加水印
     53             BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
     54             Graphics2D g = bufImg.createGraphics();
     55             g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
     56             //根据图片的背景设置水印颜色
     57             g.setColor(markContentColor);
     58             //设置字体
     59             g.setFont(font);
     60             //设置时间水印的坐标
     61             int x = (int) (srcImgWidth - 1.64*getWatermarkLength(waterMarkContent, g));
     62             int y = (int) (srcImgHeight - 1.15*getWatermarkLength(waterMarkContent, g));
     63             int x2 = 0;
     64             int y2 = 0;
     65             //设置姓名水印坐标
     66             if (workerNames.length() == 3){
     67                  x2 = (int) (srcImgWidth - 7.4*getWatermarkLength(workerNames,g));
     68                  y2 = (int) (srcImgHeight - 7.27*getWatermarkLength(workerNames,g));
     69             }else if (workerNames.length() == 2){
     70                  x2 = (int) (srcImgWidth - 11*getWatermarkLength(workerNames,g));
     71                  y2 = (int) (srcImgHeight - 10.9*getWatermarkLength(workerNames,g));
     72             }else if (workerNames.length() == 4){
     73                 x2 = (int) (srcImgWidth - 5.9*getWatermarkLength(workerNames,g));
     74                 y2 = (int) (srcImgHeight - 5.45*getWatermarkLength(workerNames,g));
     75             }
     76             int x3 =0;
     77             int y3 =0;
     78             if (workerCardNums.length() == 18){
     79                 //设置身份证号水印坐标
     80                 x3 = (int) (srcImgWidth - 1.6*getWatermarkLength(workerCardNums,g));
     81                 y3 = (int) (srcImgHeight - 0.4*getWatermarkLength(workerCardNums,g));
     82             }else if (workerCardNums.length() == 17){
     83                 x3 = (int) (srcImgWidth - 1.7*getWatermarkLength(workerCardNums,g));
     84                 y3 = (int) (srcImgHeight - 0.42*getWatermarkLength(workerCardNums,g));
     85             }else if (workerCardNums.length() == 16){
     86                 x3 = (int) (srcImgWidth - 1.8*getWatermarkLength(workerCardNums,g));
     87                 y3 = (int) (srcImgHeight - 0.45*getWatermarkLength(workerCardNums,g));
     88             }
     89             //设置组织名称水印坐标
     90             int x4 = srcImgWidth - 2*getWatermarkLength(allStaffOrgNames,g);
     91             int y4 = srcImgHeight - 3*getWatermarkLength(allStaffOrgNames,g);
     92             int x5 = 0;
     93             int y5 = 0;
     94             if (studentScores.longValue() >= 100){
     95                 //设置分数水印坐标
     96                 x5 = (int) (srcImgWidth - 11.8*getWatermarkLength(String.valueOf(studentScores),g));
     97                 y5 = (int) (srcImgHeight - 9.7*getWatermarkLength(String.valueOf(studentScores),g));
     98             }else if (studentScores.longValue() <10 && studentScores.longValue()>= 0){
     99                 //设置分数水印坐标
    100                 x5 = (int) (srcImgWidth - 35*getWatermarkLength(String.valueOf(studentScores),g));
    101                 y5 = (int) (srcImgHeight - 28.99*getWatermarkLength(String.valueOf(studentScores),g));
    102             }else if (studentScores.longValue() <= 99 && studentScores.longValue()> 10){
    103                 //设置分数水印坐标
    104                 x5 = (int) (srcImgWidth - 17.4*getWatermarkLength(String.valueOf(studentScores),g));
    105                 y5 = (int) (srcImgHeight - 14.5*getWatermarkLength(String.valueOf(studentScores),g));
    106             }
    107 
    108             //设置证书编号水印坐标
    109             int x6 = 0;
    110             int y6 = 0;
    111             if (certNums.length() == 15){
    112                 x6 = (int) (srcImgWidth - 2.09*getWatermarkLength(certNums,g));
    113                 y6 = (int) (srcImgHeight - 4.14*getWatermarkLength(certNums,g));
    114             }
    115             //设置证书名称水印坐标
    116             int x7 = srcImgWidth - 3*getWatermarkLength(trainCredentialNames,g);
    117             int y7 = srcImgHeight - 2*getWatermarkLength(trainCredentialNames,g);
    118             //设置模板内容水印坐标
    119             int x8 = srcImgWidth - 1*getWatermarkLength(templateContents,g);
    120             int y8 = srcImgHeight - 1*getWatermarkLength(templateContents,g);
    121 
    122             //画出水印
    123             g.drawString(waterMarkContent,x,y);
    124             g.drawString(workerNames,x2,y2);
    125             g.drawString(workerCardNums,x3,y3);
    126            /* g.drawString(allStaffOrgNames,x4,y4);*/
    127             g.drawString(String.valueOf(studentScores),x5,y5);
    128             g.drawString(certNums,x6,y6);
    129             /*g.drawString(trainCredentialNames,x7,y7);
    130             g.drawString(templateContents,x8,y8);*/
    131             g.dispose();
    132             // 输出图片
    133 //            FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
    134 //            ImageIO.write(bufImg, "jpeg", outImgStream);
    135             System.out.println("添加水印完成");
    136             return bufImg;
    137         } catch (Exception e) {
    138             // TODO: handle exception
    139         }
    140         return null;
    141     }
    142 
    143     private byte[] readInputStream(InputStream inputStream) throws IOException {
    144         ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    145         //创建一个Buffer字符串
    146         byte[] buffer = new byte[1024];
    147         //每次读取的字符串长度,如果为-1,代表全部读取完毕
    148         int len = 0;
    149         //使用一个输入流从buffer里把数据读取出来
    150         while( (len=inputStream.read(buffer)) != -1 ){
    151             //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
    152             outStream.write(buffer, 0, len);
    153         }
    154         //关闭输入流
    155         inputStream.close();
    156         //把outStream里的数据写入内存
    157         return outStream.toByteArray();
    158     }
    159 
    160     public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
    161         return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    162     }
    163 }
  • 相关阅读:
    An introduction to parsing text in Haskell with Parsec
    Kafka and ZooKeeper
    Kotlin + Anko for Android
    LibGDX
    OpenCV
    大中型网站技术实践系列
    Go by Example
    Benchmarks for the Top Server-Side Swift Frameworks vs. Node.js
    The Languages and Frameworks You Should Learn in 2017
    RabbitMQ
  • 原文地址:https://www.cnblogs.com/shxkey/p/12739955.html
Copyright © 2020-2023  润新知