springBoot 给图片添加文字水印

项目要求给每个考生制作证书。这里我们有每个公司需要的背景图片模板,而我现在要做的就是把每个考生的考试信息和个人信息,以水印的形式添加到图片的指定位置。(现在这个灵活性不高)下面就直接上代码。

  1. 首先我这边先写了一个工具类waterMarkUtils 。在这个工具类里面主要设置每个水印的位置以及字体还有存放位置。(我这边因为要上传到服务器,所以就稍微处理了一下,还有我这个可以添加多个水印,图片的来源是网络路径)代码如下:
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;public class WaterMarkUtils {/*** @param srcImgPath 源图片路径* @param tarImgPath 保存的图片路径* @param waterMarkContent 水印内容* @param markContentColor 水印颜色* @param font 水印字体* @param workerNames*/public static Object addWaterMark(String srcImgPath, String tarImgPath, String waterMarkContent, String workerNames,String workerCardNums, String allStaffOrgNames, BigDecimal studentScores, String certNums, String trainCredentialNames,String templateContents, Color markContentColor, Font font) {try {//new一个url对象URL url = new URL(srcImgPath);//打开链接HttpURLConnection  conn = (HttpURLConnection)url.openConnection();//设置请求方式/*conn.setRequestMethod("GET");*///超时相应时间为5秒conn.setConnectTimeout(5*1000);//通过输入流获取图片数据InputStream inputStream = null;try {inputStream = conn.getInputStream();}catch (Exception e){e.printStackTrace();}//文件转化为图片Image srcImg = null;try {srcImg = ImageIO.read(inputStream);}catch (Exception e){e.printStackTrace();}//获取图片的宽int srcImgWidth = srcImg.getWidth(null);//获取图片的高int srcImgHeight = srcImg.getHeight(null);// 加水印BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);Graphics2D g = bufImg.createGraphics();g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);//根据图片的背景设置水印颜色g.setColor(markContentColor);//设置字体g.setFont(font);//设置时间水印的坐标int x = (int) (srcImgWidth - 1.64*getWatermarkLength(waterMarkContent, g));int y = (int) (srcImgHeight - 1.15*getWatermarkLength(waterMarkContent, g));int x2 = 0;int y2 = 0;//设置姓名水印坐标if (workerNames.length() == 3){x2 = (int) (srcImgWidth - 7.4*getWatermarkLength(workerNames,g));y2 = (int) (srcImgHeight - 7.27*getWatermarkLength(workerNames,g));}else if (workerNames.length() == 2){x2 = (int) (srcImgWidth - 11*getWatermarkLength(workerNames,g));y2 = (int) (srcImgHeight - 10.9*getWatermarkLength(workerNames,g));}else if (workerNames.length() == 4){x2 = (int) (srcImgWidth - 5.9*getWatermarkLength(workerNames,g));y2 = (int) (srcImgHeight - 5.45*getWatermarkLength(workerNames,g));}int x3 =0;int y3 =0;if (workerCardNums.length() == 18){//设置身份证号水印坐标x3 = (int) (srcImgWidth - 1.6*getWatermarkLength(workerCardNums,g));y3 = (int) (srcImgHeight - 0.4*getWatermarkLength(workerCardNums,g));}else if (workerCardNums.length() == 17){x3 = (int) (srcImgWidth - 1.7*getWatermarkLength(workerCardNums,g));y3 = (int) (srcImgHeight - 0.42*getWatermarkLength(workerCardNums,g));}else if (workerCardNums.length() == 16){x3 = (int) (srcImgWidth - 1.8*getWatermarkLength(workerCardNums,g));y3 = (int) (srcImgHeight - 0.45*getWatermarkLength(workerCardNums,g));}//设置组织名称水印坐标int x4 = srcImgWidth - 2*getWatermarkLength(allStaffOrgNames,g);int y4 = srcImgHeight - 3*getWatermarkLength(allStaffOrgNames,g);int x5 = 0;int y5 = 0;if (studentScores.longValue() >= 100){//设置分数水印坐标x5 = (int) (srcImgWidth - 11.8*getWatermarkLength(String.valueOf(studentScores),g));y5 = (int) (srcImgHeight - 9.7*getWatermarkLength(String.valueOf(studentScores),g));}else if (studentScores.longValue() <10 && studentScores.longValue()>= 0){//设置分数水印坐标x5 = (int) (srcImgWidth - 35*getWatermarkLength(String.valueOf(studentScores),g));y5 = (int) (srcImgHeight - 28.99*getWatermarkLength(String.valueOf(studentScores),g));}else if (studentScores.longValue() <= 99 && studentScores.longValue()> 10){//设置分数水印坐标x5 = (int) (srcImgWidth - 17.4*getWatermarkLength(String.valueOf(studentScores),g));y5 = (int) (srcImgHeight - 14.5*getWatermarkLength(String.valueOf(studentScores),g));}//设置证书编号水印坐标int x6 = 0;int y6 = 0;if (certNums.length() == 15){x6 = (int) (srcImgWidth - 2.09*getWatermarkLength(certNums,g));y6 = (int) (srcImgHeight - 4.14*getWatermarkLength(certNums,g));}//设置证书名称水印坐标int x7 = srcImgWidth - 3*getWatermarkLength(trainCredentialNames,g);int y7 = srcImgHeight - 2*getWatermarkLength(trainCredentialNames,g);//设置模板内容水印坐标int x8 = srcImgWidth - 1*getWatermarkLength(templateContents,g);int y8 = srcImgHeight - 1*getWatermarkLength(templateContents,g);//画出水印g.drawString(waterMarkContent,x,y);g.drawString(workerNames,x2,y2);g.drawString(workerCardNums,x3,y3);/* g.drawString(allStaffOrgNames,x4,y4);*/g.drawString(String.valueOf(studentScores),x5,y5);g.drawString(certNums,x6,y6);/*g.drawString(trainCredentialNames,x7,y7);g.drawString(templateContents,x8,y8);*/g.dispose();// 输出图片
//            FileOutputStream outImgStream = new FileOutputStream(tarImgPath);
//            ImageIO.write(bufImg, "jpeg", outImgStream);System.out.println("添加水印完成");return bufImg;} catch (Exception e) {// TODO: handle exception}return null;}private byte[] readInputStream(InputStream inputStream) throws IOException {ByteArrayOutputStream outStream = new ByteArrayOutputStream();//创建一个Buffer字符串byte[] buffer = new byte[1024];//每次读取的字符串长度,如果为-1,代表全部读取完毕int len = 0;//使用一个输入流从buffer里把数据读取出来while( (len=inputStream.read(buffer)) != -1 ){//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度outStream.write(buffer, 0, len);}//关闭输入流inputStream.close();//把outStream里的数据写入内存return outStream.toByteArray();}public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());}
}

然后就是自己写查询的代码了,我这里是直接在serviceImpl 实现类里面调用的这个工具类 代码如下:

service层接口:

serviceImpl实现类:

 /*** 获取证书需要的字段* @return*/@Overridepublic Map<String,Object> getAllStaffTrainWorker(JSONObject jsonParam) {String allStaffWorkerId = jsonParam.getString("allStaffWorkerIds");if (null == allStaffWorkerId){errLog("getAllStaffTrainWorker", ErrorCodeMsg.PARAM_ERROR.getMessage(), "员工id不存在");throw new AttemptException(ErrorCodeMsg.PARAM_ERROR,"员工id不存在");}//员工表查询出员工的基本信息Example example = new Example(AllStaffTrainWorker.class);Example.Criteria criteria = example.createCriteria();criteria.andEqualTo("isDeleted", CmnConstants.IS_DELETED_NO);criteria.andEqualTo("isEnabled", CmnConstants.IS_ENABLED_YES);String [] allStaffWorkerArry = allStaffWorkerId.split(",");List<Long> allStaffWorkerIds = new ArrayList<>();for (String allStaffWorkerIdss :allStaffWorkerArry){allStaffWorkerIds.add(Long.valueOf(allStaffWorkerIdss));}criteria.andIn("allStaffWorkerId",allStaffWorkerIds);List<AllStaffTrainWorker> allStaffTrainWorkerList = this.allStaffTrainWorkerMapper.selectByExample(example);//姓名String workerName = null;//身份证号String workerCardNum = null;//组织名称String allStaffOrgName = null;//学员得分BigDecimal studentScore = null;//证书编号String certNum = null;//证书名称String trainCredentialName = null;//获取模板内容String templateContent = null;//获取背景图片路径String imgUrl =null;if (null != allStaffTrainWorkerList){for (AllStaffTrainWorker allStaffTrainWorker1 : allStaffTrainWorkerList){workerName= allStaffTrainWorker1.getWorkerName();workerCardNum = allStaffTrainWorker1.getWorkerCardNum();allStaffOrgName = allStaffTrainWorker1.getAllStaffOrgName();}//考试表获取分数Example example1 = new Example(AllStaffTrainWorkerExam.class);Example.Criteria criteria1 = example1.createCriteria();criteria1.andEqualTo("isDeleted", CmnConstants.IS_DELETED_NO);criteria1.andEqualTo("isEnabled", CmnConstants.IS_ENABLED_YES);criteria1.andEqualTo("allStaffWorkerId",allStaffWorkerId);List<AllStaffTrainWorkerExam> allStaffTrainWorkerExamList = this.allStaffTrainWorkerExamMapper.selectByExample(example1);for (AllStaffTrainWorkerExam allStaffTrainWorkerExam : allStaffTrainWorkerExamList){studentScore =  allStaffTrainWorkerExam.getStudentScore();}//证书表得到证书编号Example example2 = new Example(AllStaffTrainWorkerCert.class);Example.Criteria criteria2 = example2.createCriteria();criteria2.andEqualTo("isDeleted", CmnConstants.IS_DELETED_NO);criteria2.andEqualTo("isEnabled", CmnConstants.IS_ENABLED_YES);criteria2.andEqualTo("allStaffWorkerId",allStaffWorkerId);List<AllStaffTrainWorkerCert> allStaffTrainWorkerCertList = this.allStaffTrainWorkerCertMapper.selectByExample(example2);Long allStaffTrainCertId = null;for (AllStaffTrainWorkerCert allStaffTrainWorkerCert : allStaffTrainWorkerCertList){certNum =  allStaffTrainWorkerCert.getCertNum();allStaffTrainCertId = allStaffTrainWorkerCert.getAllStaffTrainCertId();}//配置证书表获取证书名称Example example3= new Example(AllStaffTrainCert.class);Example.Criteria criteria3 = example3.createCriteria();criteria3.andEqualTo("isDeleted", CmnConstants.IS_DELETED_NO);criteria3.andEqualTo("isEnabled", CmnConstants.IS_ENABLED_YES);criteria3.andEqualTo("allStaffTrainCertId",allStaffTrainCertId);List<AllStaffTrainCert> allStaffTrainCertList = this.allStaffTrainCertMapper.selectByExample(example3);//模板idLong allStaffTrainTemplateId = null;//图片idLong allStaffTrainImgId = null;for (AllStaffTrainCert allStaffTrainCert : allStaffTrainCertList){trainCredentialName = allStaffTrainCert.getTrainCredentialName();allStaffTrainTemplateId = allStaffTrainCert.getAllStaffTrainTemplateId();allStaffTrainImgId = allStaffTrainCert.getAllStaffTrainImgId();}Example example4 = new Example(AllStaffTrainCertTemplate.class);Example.Criteria criteria4 = example4.createCriteria();criteria4.andEqualTo("isDeleted", CmnConstants.IS_DELETED_NO);criteria4.andEqualTo("isEnabled", CmnConstants.IS_ENABLED_YES);criteria4.andEqualTo("allStaffTrainTemplateId",allStaffTrainTemplateId);AllStaffTrainCertTemplate allStaffTrainCertTemplate = this.allStaffTrainCertTemplateMapper.selectOneByExample(example4);//获取模板内容templateContent = allStaffTrainCertTemplate.getTemplateContent();Example example5 = new Example(AllStaffTrainCertImg.class);Example.Criteria criteria5 = example5.createCriteria();criteria5.andEqualTo("isDeleted", CmnConstants.IS_DELETED_NO);criteria5.andEqualTo("isEnabled", CmnConstants.IS_ENABLED_YES);criteria5.andEqualTo("allStaffTrainImgId",allStaffTrainImgId);AllStaffTrainCertImg allStaffTrainCertImg = this.allStaffTrainCertImgMapper.selectOneByExample(example5);//获取背景图片路径imgUrl = allStaffTrainCertImg.getImgUrl();}ClassPathResource classPathResource = new ClassPathResource("fonts/msyh.ttc");InputStream inputStream = null;try {inputStream = classPathResource.getInputStream();}catch (Exception e){e.getMessage();}Font dynamicFont = null;try {dynamicFont = Font.createFont(Font.TRUETYPE_FONT, inputStream);}catch (Exception e){e.printStackTrace();}Font font = dynamicFont.deriveFont(Font.PLAIN, 28); //水印字体 方法3//水印字体/*Font font = new Font("微软雅黑", Font.PLAIN, 28);*///源图片地址String srcImgPath="http://"+imgUrl;//待存储的地址String tarImgPath = "F:/证书.jpeg";//格式化时间SimpleDateFormat f=new SimpleDateFormat("yyyy     MM     dd");String format = f.format(new Date());//时间String waterMarkContent=format;//姓名String workerNames = workerName;//身份证号String workerCardNums = workerCardNum;//组织名称String allStaffOrgNames = allStaffOrgName;//学员得分BigDecimal studentScores = studentScore;//证书编号String certNums =certNum;//证书名称String trainCredentialNames = trainCredentialName;//获取模板内容String templateContents = templateContent;//水印图片色彩以及透明度Color color=new Color(79 ,79 ,79);BufferedImage bufferedImage = (BufferedImage) WaterMarkUtils.addWaterMark(srcImgPath, tarImgPath, waterMarkContent, workerNames, workerCardNums, allStaffOrgNames, studentScores, certNums, trainCredentialNames, templateContents, color, font);String sessionToke =jsonParam.getString("sessionToke");String attname = "证书"+".jpeg";String url = null;try {byte[] jpegs = imageToBytes(bufferedImage, "jpeg");url = FastDFSUtils.getDoUpload(sessionToke,attname,jpegs);}catch (Exception e){errLog("getDownloadAllStaffWorkers",ErrorCodeMsg.UNKNOWN_ERROR.getMessage(),e.getMessage());throw new AttemptException(ErrorCodeMsg.UNKNOWN_ERROR,e.getMessage());}Map<String, Object> resultMap = getFastDFSFileInfoMap(url,attname);return resultMap;}public  byte[] imageToBytes(BufferedImage bImage, String format) {ByteArrayOutputStream out = new ByteArrayOutputStream();try {ImageIO.write(bImage, format, out);} catch (IOException e) {e.printStackTrace();}return out.toByteArray();}/*** 返回给前端下载地址** @param url* @param attname* @return*/private Map<String, Object> getFastDFSFileInfoMap(String url, String attname) {String filePath = null;if (StringUtils.isNotEmpty(url)) {JSONObject jsonObject = JSONObject.parseObject(url);String data = jsonObject.getString("data");JSONObject dataObject = JSONObject.parseObject(data);filePath = dataObject.getString("filePath");if (StringUtils.isEmpty(filePath)) {errLog("getFastDFSFileInfoMap", ErrorCodeMsg.UNKNOWN_ERROR.getMessage(), "获取文件服务下载地址为空");throw new AttemptException(ErrorCodeMsg.UNKNOWN_ERROR, "获取文件服务下载地址为空");}}Map<String, Object> map = new HashMap<>(32);map.put("url",fileServer+"/"+filePath);map.put("attname", attname);return map;}

controller层代码

/*** 证书需要的内容* @return*/@PostMapping("/getAllStaffTrainWorker")public ResponseStruct getAllStaffTrainWorker(@RequestBody JSONObject jsonParam){return ResponseStruct.success(this.allStaffTrainWorkerCertInterface.getAllStaffTrainWorker(jsonParam));}

总结:
这里面的坑:
1.图片是我们这边上传到服务器的所以数据库存放的的 url 而且输入到浏览器可以直接下载的。所以读取文件url的时候,我进行了了处理 具体代码就在工具类最上面
2.每个水印因为文字的字体和大小变动,位置也会变动
3.刚一开始文字字体用的Windows自带的字体,上传到服务器之后,因为服务器没有字体。要么下载一个要么想我这样 把字体包放到项目根目录然后再用流方式获取。
4.字体包位置

springboot——图片添加文字水印相关推荐

  1. Springboot中给图片添加文字水印

    Springboot中给图片添加文字水印 工作中遇到给图片添加文字水印的需求,记录下来方便之后查阅 需求内容: 给一张图片添加指定文字水印,使一张图片上有多个水印内容,并且设定一个水印开关,可指定是否 ...

  2. Swift - 给图片添加文字水印(图片上写文字,并可设置位置和样式)

    想要给图片添加文字水印或者注释,我们需要实现在UIImage上写字的功能. 1,效果图如下: (在图片左上角和右下角都添加了文字.) 2,为方便使用,我们通过扩展UIImage类来实现添加水印功能 ( ...

  3. php生成背景并加字,PHP给图片添加文字水印实例

    PHP给图片添加文字水印实例,支持中文文字水印,是否覆盖原图,自定义设置水印背景色.文字颜色.字体等. 水印类water.class.php var $Path = "./"; / ...

  4. 二、VB.NET实现给图片添加文字水印

    VB.NET实现给图片添加文字水印 通过vb.net给选定的图片添加文字水印,添加的文字从文本文档中获取,可以一次给相同的图片添加不同的文字水印,并以添加的文字命名图片: Imports System ...

  5. python 实现图片添加文字水印

    在python中我们可以使用openCV给图片添加水印,这里注意openCV无法添加汉字水印,添加汉字水印上可使用PIL库给图片添加水印 一:openCV给图片添加水印 1:安装openCV pip ...

  6. android水印控件,Android图片添加文字水印并保存水印文字图片到指定文件

    Android图片添加文字水印并保存水印文字图片到指定文件package zhangphil.test;import android.graphics.Bitmap;import android.gr ...

  7. php给图片添加文字水印

    PHP对图片的操作用到GD库,这里我们介绍如何给图片添加文字水印. 大致分为四步: 1.打开图片 2.操作图片 3.输出图片 4.销毁图片 下面我们上代码来具体讲解每步的实现过程: <?php/ ...

  8. JAVA 给图片添加文字水印

    水印操作有很多,例如:给图片添加文字.图片水印,给pdf文件添加水印,给文件加盖公章,这类需求还是时常会遇到的,今天就简单记录一下给图片添加文字水印的demo,仅供大家参考,后续会写别的情况的添加水印 ...

  9. Java分享--给图片添加文字水印(文字可旋转)

    这篇文章主要介绍了Java实现给图片添加文字水印,文字水印的方法,涉及java针对图片的读取.水印添加设置等相关操作技巧,需要的朋友可以参考下 . 很多时候项目中的图片需要一定的版权,就是人家拿出去用 ...

最新文章

  1. 影响程序员生涯的三个错误观念,你千万不要犯!
  2. c++ 低位在前 高位在后_A股市场:如果股票涨停后第二天“高开低走”,你知道怎么操作才能利益最大化吗?...
  3. C++ primer第六章6.5函数的学习 之特殊用途的语言特性
  4. 下架77天后 小红书恢复上架安卓应用市场
  5. java代码 网站_推荐几个比较好的Java代码查询网站
  6. projecteuler_problem11
  7. 超400万用户的Chrome截图插件下架始末
  8. Linux服务器php7.3,安装zip扩展
  9. java cipher.dofinal_cipher.dofinal方法
  10. 向量化编程:arrayfun及cellfun函数的使用
  11. jsp实验管理系统开题报告_MR教育燧光与广东实验中学关于MR化学课程开题报告研讨会顺利完成...
  12. access 链接mysql数据库教程_ACCESS实例教程(数据库的编程)
  13. 1960-2019年世界各国人均GDP增长率
  14. Java工程师 操作系统(四) 面试题(Day35)
  15. 从零开发HarmonyOS(鸿蒙)手机小游戏——数字华容道
  16. Outlook创建不了Skype会议的解决方案
  17. rc52实现的部分代码
  18. “燕云十六将”之张永生(13)
  19. 三方支付公司有哪些?
  20. JavaScript操作摄像头指南

热门文章

  1. boost I 常用算法组件
  2. QT调用Saleae C#生成的dll文件
  3. RabbitMQ 重置用户名和密码的方法
  4. linux命令行下写for语句,Linux下Shell的for循环语句示例
  5. JDBC、驱动管理器与DataSource
  6. 广州非按揭购房提取住房公积金攻略
  7. 计算机应用英文怎么说,电脑用英文怎么写?
  8. 数据结构实验之排序四:寻找大富翁__咳咳咳,还魂篇!!
  9. 服务器租用的费用是怎么计算的
  10. 精选SpringBoot笔记,华为19级高工亲撰1700页笔记真的太强了