记录一个制作图片水印的功能

功能介绍

对图片生成图片水印或者文字水印 ,用户可以自定义自己的图片水印

思路就是将文字和图片水印合成到一张图片上面去,前台展示合成效果

后台合成后保存到cos上面,并在数据库保存相关信息,方便用户下次引用

前台样式

在这里插入图片描述
在这里插入图片描述

后端代码

接参DTO


@Data
public class WatermarkTemplateDTO extends BasePageParamDTO{/*** 主键ID*/@ApiModelProperty(value="主键ID")private Long id;/*** 用户名*/@ApiModelProperty(value="用户名")private Long userId;/*** 水印名称*/@ApiModelProperty(value="水印名称")private String watermarkName;/*** 合成后的水印图片地址*/@ApiModelProperty(value="合成后的水印图片地址")private String watermarkUrl;/*** 素材图片URL地址*/@ApiModelProperty(value="素材图片URL地址")private String picUrl;/*** 图片透明度*/@ApiModelProperty(value="图片透明度")private Integer picOpacity;/*** 图片左边距*/@ApiModelProperty(value="图片左边距")private Integer picLeft;/*** 图片上边距*/@ApiModelProperty(value="图片上边距")private Integer picTop;/*** 图片宽度*/@ApiModelProperty(value="图片宽度")private Integer picWidth;/*** 图片高度*/@ApiModelProperty(value="图片高度")private Integer picHeight;/*** 水印文字*/@ApiModelProperty(value="水印文字")private String watermarkText;/*** 文字透明度*/@ApiModelProperty(value="文字透明度")private Float textOpacity;/*** 文字字体大小*/@ApiModelProperty(value="文字字体大小")private Integer textSize;/*** 文字字体颜色*/@ApiModelProperty(value="文字字体颜色")private String textColor;/*** 文字位置-距离图片的左边距*/@ApiModelProperty(value="文字位置-距离图片的左边距")private Integer textLeft;/*** 文字位置-距离图片的上边距*/@ApiModelProperty(value="文字位置-距离图片的上边距")private Integer textTop;/*** 文字字体*/@ApiModelProperty(value="文字字体")private String textFont;/*** 图片翻转,0:不翻转  1: 水平翻转  2 : 垂直翻转*/@ApiModelProperty(value="图片翻转,0:不翻转  1: 水平翻转  2 : 垂直翻转")private Integer picTurn;/*** 图片旋转角度*/@ApiModelProperty(value="图片旋转角度")private Integer picRotate;/*** 创建时间*/@ApiModelProperty(value="创建时间")private Date createDate;}

数据库实体类

/*** 水印模板表*/
@ApiModel(value = "com-menglar-soap-item-pojo-mysql-WatermarkTemplate")
@Data
@NoArgsConstructor
@TableName(value = "item_watermark_template")
public class WatermarkTemplate implements Serializable {/*** 主键ID*/@ApiModelProperty(value = "主键ID")private Long id;/*** 用户名*/@ApiModelProperty(value = "用户名")private Long userId;/*** 水印名称*/@ApiModelProperty(value = "水印名称")private String watermarkName;/*** 合成后的水印图片地址*/@ApiModelProperty(value = "合成后的水印图片地址")private String watermarkUrl;/*** 素材图片URL地址*/@ApiModelProperty(value = "素材图片URL地址")private String picUrl;/*** 图片透明度*/@ApiModelProperty(value = "图片透明度")private Integer picOpacity;/*** 图片左边距*/@ApiModelProperty(value = "图片左边距")private Integer picLeft;/*** 图片上边距*/@ApiModelProperty(value = "图片上边距")private Integer picTop;/*** 图片宽度*/@ApiModelProperty(value = "图片宽度")private Integer picWidth;/*** 图片高度*/@ApiModelProperty(value = "图片高度")private Integer picHeight;/*** 水印文字*/@ApiModelProperty(value = "水印文字")private String watermarkText;/*** 文字透明度*/@ApiModelProperty(value = "文字透明度")private Float textOpacity;/*** 文字字体大小*/@ApiModelProperty(value = "文字字体大小")private Integer textSize;/*** 文字字体颜色*/@ApiModelProperty(value = "文字字体颜色")private String textColor;/*** 文字位置-距离图片的左边距*/@ApiModelProperty(value = "文字位置-距离图片的左边距")private Integer textLeft;/*** 文字位置-距离图片的上边距*/@ApiModelProperty(value = "文字位置-距离图片的上边距")private Integer textTop;/*** 文字字体*/@ApiModelProperty(value = "文字字体")private String textFont;/*** 图片翻转,0:不翻转  1: 水平翻转  2 : 垂直翻转*/@ApiModelProperty(value = "图片翻转,0:不翻转  1: 水平翻转  2 : 垂直翻转")private Integer picTurn;/*** 图片旋转角度*/@ApiModelProperty(value = "图片旋转角度")private Integer picRotate;/*** 创建时间*/@ApiModelProperty(value = "创建时间")private Date createDate;private static final long serialVersionUID = 1L;
}

水印生成方法

/*** 上传水印模板* @param wtDto* @return*/@Overridepublic Result uploadWatermarkPic(WatermarkTemplateDTO wtDto) {if (StringUtils.isBlank(wtDto.getPicUrl()) && StringUtils.isBlank(wtDto.getWatermarkText())) {throw new BusinessException("素材图片/水印文字不能为空");}try {BufferedImage output = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);Graphics2D g2 = output.createGraphics();output = g2.getDeviceConfiguration().createCompatibleImage(800, 800, Transparency.TRANSLUCENT);g2 = output.createGraphics();//调制透明度for (int j1 = output.getMinY(); j1 < output.getHeight(); j1++) {for (int j2 = output.getMinX(); j2 < output.getWidth(); j2++) {int rgb = output.getRGB(j2, j1);rgb = ((0 * 255 / 10) << 24) | (rgb & 0x00ffffff);output.setRGB(j2, j1, rgb);}}//1、先画一张完全透明的背景图g2.drawImage(output, 0, 0, 800, 800, null);//图片水印if(StringUtils.isNotBlank(wtDto.getPicUrl())){log.info("图片参数:opacity:{},height:{},picLeft:{},picTop:{},picWidth:{}", wtDto.getPicOpacity(), wtDto.getPicHeight(), wtDto.getPicLeft(), wtDto.getPicTop(), wtDto.getPicWidth());Integer alpha = wtDto.getPicOpacity();if(alpha == null|| wtDto.getPicOpacity() == null|| wtDto.getPicHeight() == null|| wtDto.getPicLeft() == null|| wtDto.getPicTop() == null|| wtDto.getPicWidth() == null){throw new BusinessException("图片参数错误!");}//检查透明度是否越界if (alpha < 0) {alpha = 0;} else if (alpha > 10) {alpha = 10;}InputStream inputStream = CompositeWatermarkUtil.downloadFile(wtDto.getPicUrl());BufferedImage image = ImageIO.read(inputStream);//2、再画水印素材图片g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,alpha.floatValue()/10));g2.drawImage(image, equalRatioCalculation(wtDto.getPicLeft()), equalRatioCalculation(wtDto.getPicTop()), equalRatioCalculation(wtDto.getPicWidth()), equalRatioCalculation(wtDto.getPicHeight()), null);}//文字水印if (StringUtils.isNotBlank(wtDto.getWatermarkText())) {log.info("文字参数:textLeft:{},TextLeft:{},TextOpacity:{},TextColor:{},TextSize:{},TextFont:{}", wtDto.getTextLeft(), wtDto.getTextTop(), wtDto.getTextOpacity(), wtDto.getTextColor(), wtDto.getTextSize(), wtDto.getTextFont());if(wtDto.getTextLeft() == null|| wtDto.getTextTop() == null|| wtDto.getTextOpacity() == null|| wtDto.getTextColor() == null|| wtDto.getTextSize() == null|| wtDto.getTextFont() == null){throw new BusinessException("文字参数错误!");}try {String[] availableFontFamilyNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();log.info("测试环境字体列表数组为:" + availableFontFamilyNames);if(availableFontFamilyNames != null){log.info("测试环境字体列表数组长度:" + availableFontFamilyNames.length);log.info("测试环境字体列表获取首个:" + availableFontFamilyNames[0]);}for(String s : availableFontFamilyNames){log.info(s);}} catch (Exception e) {e.printStackTrace();}//3、画文字String textColor = wtDto.getTextColor();//字体Font font = new Font(wtDto.getTextFont(), Font.BOLD, wtDto.getTextSize());//水印字体,大小//颜色Color color = new Color(Integer.decode(textColor));g2.setFont(font);g2.setColor(color);g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, wtDto.getTextOpacity()));log.info("画文字开始");g2.drawString(wtDto.getWatermarkText(), equalRatioCalculation(wtDto.getTextLeft()), equalRatioCalculation(wtDto.getTextTop()));log.info("画文字结束");}//上传合成的水印ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();ImageIO.write(output, "png", arrayOutputStream);byte[] bytes = arrayOutputStream.toByteArray();ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);Long userId = SecurityUtils.getUserId();//如果是编辑后保存,则有水印模板URL,使用原水印模板地址,新水印模板会替换掉旧的if (BeanUtil.isNotEmpty(wtDto.getId())) {WatermarkTemplate watermarkTemplate = watermarkTemplateMapper.selectOne(Wrappers.lambdaQuery(WatermarkTemplate.class).eq(WatermarkTemplate::getId, wtDto.getId()));String key = cosClient.buildKey(watermarkTemplate.getWatermarkUrl());cosClient.uploadFile(byteArrayInputStream, key);BeanUtil.copyProperties(wtDto, watermarkTemplate, CopyOptions.create().setIgnoreError(true).ignoreNullValue());watermarkTemplateMapper.updateByPrimaryKeySelective(watermarkTemplate);} else {//没有水印模板URL则是新增水印模板,生成新的String key = cosClient.buildStoragePath(FileTypeEnum.IMAGE, "png", userId);String watermarkTemplateUrl = cosClient.uploadFile(byteArrayInputStream, key);WatermarkTemplate watermarkTemplate = new WatermarkTemplate();BeanUtil.copyProperties(wtDto, watermarkTemplate, CopyOptions.create().setIgnoreError(true).ignoreNullValue());watermarkTemplate.setWatermarkUrl(watermarkTemplateUrl);watermarkTemplate.setCreateDate(new Date());watermarkTemplate.setUserId(userId);watermarkTemplateMapper.insert(watermarkTemplate);}return Result.ok(StatusCode.SUCCESS, "保存水印成功");} catch (Exception e) {e.printStackTrace();return Result.errorMessage("保存水印失败,系统异常", StatusCode.FAILURE.code());}}/*** 水印素材位置等比例计算* @param value* @return*/private Integer equalRatioCalculation(Integer value){BigDecimal waterSize = new BigDecimal(800);//水印最大尺寸BigDecimal editerSize = new BigDecimal(500);//前端编辑框尺寸BigDecimal ratio = editerSize.divide(waterSize);BigDecimal valBd = new BigDecimal(value);BigDecimal finalVal = valBd.divide(ratio);int i = finalVal.intValue();return i;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/24172.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用Thumbnilator对图片加文字水印

引言&#xff1a; 最近有给图片添加水印的需求&#xff0c;于是找了Thumbnailator工具&#xff1b;Thumbnailator中可以方便的对图片增加图片水印&#xff0c;但是在添加文字水印上却没有方法。 版本一&#xff08;未使用Thumbnailator依赖&#xff09;&#xff1a; /*** aut…

数字水印算法

任务背景及简介 随着互联网的普及和数字技术的广泛应用&#xff0c;信息媒体的数字化极大地提高了信息的存取效率, Intenet 的普及又为数字信息在世界范围内的迅速传递开辟了便捷的途径&#xff0c;数字产品变得极大丰富并且传播便捷&#xff0c;但与此同时版权保护问题也日益突…

数字图像中添加水印

实际上,在产品里能够设置密码并且在产品中添加水印是最理想的防盗措施,因为设置密码是为了防止别人剽窃技术或使用产品,而添加水印更多的是一种补救措施,是在他人成功盗取自己技术的前提下,在法律上夺取主动权的砝码。下面来介绍一下如何在MATLAB中实现往数字图像中添加水印效果…

信息隐藏与数字水印技术

1 信息隐藏 1. 1 信息隐藏模型信息隐藏 (Information Hiding)不同于传统的密码学技术。密码技术主要是研究如何将机密信息进行特殊的编码&#xff0c;以形成不可识别的密码形式 (密文 )进行传递&#xff1b;而信息隐藏则主要研究如何将某一机密信息秘密隐藏于另一公开的信息…

给图片加盲水印(数字水印)所有功能免费使用

盲水印是不可见&#xff0c;但实际存在图片中的水印。需通过特殊的技术手段才能获取到水印。 . 一次可以给十张图片加图片水印或文字水印&#xff0c;不限使用次数 . 只能给单张图片解水印且需要原水印图片或水印文字 . 水印密码必须为数字&#xff0c;可设可不设。如设置了…

“数字水印”来临,一波“反ChatGPT”的技术开始冒头 | 星球资讯

数科星球 原创 作者丨数数 编辑丨十里香 ChatGPT爆火&#xff0c;对于这项技术来说&#xff0c;似乎无所不能。从作曲、小说、文章再到编剧&#xff0c;人们这些天为该项技术忙活的不亦乐乎。 但事情很快得到了反转&#xff0c;有些人开始担心这项新的技术会被坏人所利用。而…

微软半日游,和CSDN同学们走进名企

上周三&#xff08;2021-11-24&#xff09;&#xff0c;跟随 CSDN 《新程序员》组织的 "走进名企"活动&#xff0c;和邹欣老师等一众大佬们探访了北京微软亚洲研究院。真是一次令我开眼界的旅程&#xff0c;一起看看~ 作为一个普普通通的北漂程序员来说&#xff0c;大…

Seata 与三大平台携手编程之夏,百万奖金等你来拿

作者&#xff1a;Seata社区 社区简介 Seata 是一款开源的分布式事务解决方案&#xff0c;致力于在微服务架构下提供高性能和简单易用的分布式事务服务。在 Seata 开源之前&#xff0c;Seata 在阿里系内部一直扮演着分布式数据一致性中间件的角色&#xff0c;几乎每笔交易都要…

阿里技术官整合的四大主流中间件笔记,让你高薪摸鱼,不再秃头背锅

RabbitMQ&#xff1a; 优点&#xff1a;轻量&#xff0c;迅捷&#xff0c;容易部署和使用&#xff0c;拥有灵活的路由配置 缺点&#xff1a;性能和吞吐量较差&#xff0c;不易进行二次开发 RocketMQ&#xff1a; 优点&#xff1a;性能好&#xff0c;稳定可靠&#xff0c;有活…

一位微软技术大牛,工作8年的职业经验分享

写在前面 进击的叻叻是小灰的一位朋友&#xff0c;本文整理了他今年9月返校进行校友职场经验分享的内容&#xff0c;从职业选择、职业发展、工作体验和职业认知四个方面&#xff0c;分享自己微软八年职业生涯的经历和感悟。 这篇文章是对当时校友职场经验分享会内容的精炼和补充…

尚硅谷商品汇项目复习文档

项目资料 项目源码&#xff1a;https://gitee.com/HusePanghu/project-SP 项目地址&#xff1a;HusePanghu.SPH 前言 提示&#xff1a;本文档的编撰初衷是用于复习和回顾该项目&#xff0c;而非该项目的教程文档&#xff0c;弊处多多&#xff0c;敬请包涵。欢迎大家在评论区交…

千橡CEO陈一舟5日聊微软入股Facebook和校内网

千橡CEO陈一舟5日聊微软入股Facebook和校内网 http://www.sina.com.cn 2007年11月01日 17:50 新浪科技 千橡集团董事长兼CEO陈一舟(新浪科技配图) 新浪科技讯 11月1日消息&#xff0c;千橡集团董事长兼CEO陈一舟将于11月5日10:30做客新浪科技白银时代&#xff0c;届时他将就微…

今天面了个阿里秒杀项目组的,见识到了基础天花板被震撼到了

在京东工作了8年&#xff0c;工作压力大&#xff0c;节奏快&#xff0c;但是从技术上确实得到了成长&#xff0c;尤其是当你维护与大促相关的系统的时候&#xff0c;熬到P7也费了不少心思&#xff0c;小编也是个爱学习的人&#xff0c;把这几年的工作经验整理成了一份完整的笔记…

互联网暴力裁员,唯有神技面试八股文手册,能助各位码农突破囧境

很多人都说今年对于IT行业根本没有所谓的“金三银四”“金九银十”。在各大招聘网站或者软件上不管是大厂还是中小公司大多都是挂个招聘需求&#xff0c;实际并不招人&#xff1b;在行业内的程序员基本都已经感受到了任老前段时间口中所谓的“寒气”。 虽然事实确实是如此&…

27位技术实战派负责人齐聚 深聊降本增效 你一定不想错过!

倒计时6天&#xff0c;11月4日 杭州云栖大会-探索增长动能峰会即将启动 阿里巴巴集团CTO线&#xff06;阿里云智能互联网行业线& ​阿里云智能基础产品事业部联合出品 27位技术实战派负责人齐聚 共同深入讨论企业降本增效的话题 欢迎一起来 看点 1&#xff1a;27位实战…

商汤科技推出“日日新SenseNova”,大模型体系赋能人工智能新未来

2023年4月10日&#xff0c;商汤科技SenseTime技术交流日活动在上海举行&#xff0c;分享了以“大模型大算力”推进AGI&#xff08;通用人工智能&#xff09;发展的战略布局&#xff0c;并公布了商汤在该战略下的“日日新SenseNova”大模型体系。 公开信息显示&#xff0c;商汤科…

AI抢饭碗成真!近500家美国企业用ChatGPT取代员工,有公司省下超10万美元

Alex 发自 凹非寺量子位 | 公众号 QbitAI 自从ChatGPT掀起浪潮&#xff0c;不少人都在担心AI快要抢人类饭碗了。 然鹅&#xff0c;现实可能更残酷QAQ...... 据就业服务平台Resume Builder调查统计&#xff0c;在1000多家受访美国企业中&#xff0c;用ChatGPT取代部分员工的&…

阿里CEO下令所有产品接入大模型!钉钉对标微软Office,已解锁近10项新功能

丰色 发自 凹非寺量子位 | 公众号 QbitAI “阿里版GPT”通义千问邀测没过几天—— 今天&#xff0c;在2023阿里云峰会现场&#xff0c;CEO张勇就宣布&#xff1a; 阿里巴巴所有产品未来都将接入“通义千问”大模型&#xff0c;进行全面改造。 与此同时&#xff0c;通义千问的能…

GPT-3核心成员出走打造ChatGPT最强竞品!12项任务8项更强,最新估值50亿美元

衡宇 萧箫 发自 凹非寺量子位 | 公众号 QbitAI 因不满老东家成为微软附庸&#xff0c;11名OpenAI前员工怒而出走。 如今带着“ChatGPT最强竞品”杀回战场&#xff0c;新公司估值50亿美元&#xff0c;一出手就获得3亿美元融资。 这家公司名叫Anthropic&#xff0c;新推出的聊天机…

一页PPT自动生成短视频的研究

希望通过一些技术&#xff0c;将以前自己讲过的PPT转换成有解说的短视频&#xff0c;从而进行一些分发 旁白到语音 从文字转换成语音我们首先想到的就是TTS&#xff0c;这其中我也是用了各式各样的TTS&#xff0c;发现发音电子音非常强&#xff0c;听听起来很不舒服。后来发现…