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 }

 

posted @ 2020-04-20 19:41  new海  阅读(2297)  评论(0编辑  收藏  举报