SpingBoot/JAVA实现给图片加水印功能(通过thumbnailator库)_spring boot项目 图片加水印图片-程序员宅基地

技术标签: java图片加水印  thumbnailator水印  springboot图片加水印  spring水印  SpringBoot2启示录  Spring  BufferImage转输入流  

前言

最近某项目有个加水印的需求,JAVA实现给已上传的图片增加水印并输出的功能,图片A+水印B=合成带水印缓存图片C(就是不需要保存到硬盘,不占用空间),目前网上的解决方案挺多但是挺乱,于是趁机整理了一份简洁版供大家使用。这里借助了一个很强大的Thumbnails库

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

水印B
在这里插入图片描述
效果图C
在这里插入图片描述
MAVEN

<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
<!-- https://github.com/coobird/thumbnailator -->
<dependency>
	<groupId>net.coobird</groupId>
	<artifactId>thumbnailator</artifactId>
	<version>0.4.13</version>
</dependency>

核心代码

  • storageService.getPathString()仅用于获取存放图片的目录。
  • storageService.getPathString()+filename代表图片A
  • storageService.getPathString()+"watermark.png"代表水印B `BufferedImage
  • ` 为缓存的图片类,也就是我不需要save到file中去,这里就借助这个对象,如果你需要保存,可以使用toFile();
	/**
	 * JAVA给图片加水印
	 * @author zhengkai.blog.csdn.net
	 * @param filename
	 * @param response
	 * @throws IOException
	 */
	@GetMapping("/files2/{filename:.+}")
	@ResponseBody
	@Async
	public void serveFile2(@PathVariable String filename, HttpServletResponse response) throws IOException {
    
		//加载要显示的文件
		File inFile = new File(storageService.getPathString()+filename);
		//加载水印文件
		File watFile = new File(storageService.getPathString()+"watermark.png");
		//加载到BufferedImage中
		BufferedImage originalImage = ImageIO.read(inFile);
		BufferedImage waterImage = ImageIO.read(watFile);
		//调用Thumbnails库可参考(https://github.com/coobird/thumbnailator/wiki/Examples)
		//by zhengkai.blog.csdn.net
		BufferedImage thumbnail = Thumbnails.of(originalImage)
				//必须设置大小,否则有size not set的ERROR
				.size(600, 400)
				//var3表示透明度
				.watermark(Positions.BOTTOM_RIGHT, waterImage,0.2f)
				//缓存输出
				.asBufferedImage();
		//从HttpServletResponse中获取输出流
		OutputStream outputStream = response.getOutputStream();
		//将BufferedImage转换为InputStream
		InputStream inputStream = bufferedImageToInputStream(thumbnail);
		//直接COPY输出
		IOUtils.copy(inputStream, outputStream);
		//清理缓存
		IOUtils.closeQuietly(inputStream);
		IOUtils.closeQuietly(outputStream);
		//输出下载格式的图片
		/*return  ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,
				"attachment; filename=\"" + URLEncoder.encode(filename, "UTF-8") + "\"").body(thumbnail);*/
	}
	/**
	 * JAVA给图片加水印:将BufferedImage转换为InputStream
	 * @author zhengkai.blog.csdn.net
	 */
	public InputStream bufferedImageToInputStream(BufferedImage image){
    
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		try {
    
			ImageIO.write(image, "png", os);
			InputStream input = new ByteArrayInputStream(os.toByteArray());
			return input;
		} catch (IOException e) {
    
			e.printStackTrace();
		}
		return null;
	}

效果展示

Mission Compled! resolved by zhengkai.blog.csdn.net
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/moshowgame/article/details/111878562

智能推荐

Fibonacci Heap实现_fibonacciheap consolidate-程序员宅基地

文章浏览阅读740次。本算法是对<算法导论>相关章节伪代码的实现:先贴代码:#include#include#includeusing namespace std;class FibonacciHeap;class node{ friend class FibonacciHeap; node(int v):key(v),height(0),parent(NULL),left(this),righ_fibonacciheap consolidate

CSS选择器_css选择包含某个类名的节点-程序员宅基地

文章浏览阅读629次。1.简单选择器类选择器 使用时 .类名{样式1;样式2;},匹配对应类名元素 id选择器 使用时 #id{样式1;样式2;},匹配对应id的元素 标签选择器 使用时 标签名{样式1;样式2;},匹配对应标签的元素 通用元素选择器 使用时 *{样式1;样式2;},匹配所有元素 2.属性选择器以下标签名以div为例标签名[name] 所有含有name属性的di..._css选择包含某个类名的节点

ubuntu两个conda安装和切换-程序员宅基地

文章浏览阅读1.5k次。1. 下载anaconda2安装,一路默认,注意添加/home/wang/.bashrc选择yes2. 在/home/wang/envs/py3安装anaconda3,其他同anaconda23. conda create --name xxx27 python=2.7 (我的是myPy27),实际上我的包名是2.7.14版本4. conda create --name xxx36 ..._ubuntu 两个版本conda如何指定一个

计算机网络(自顶向下)第七章总结_移动性代理通告扩展中指出该代理是它所在网络的一个外部代理的字段是-程序员宅基地

文章浏览阅读1.4k次,点赞10次,收藏12次。计算机网络第七章:无线网络和移动网络7.1 概述无线网络要素:无线主机。如同在有线网络中一样,主机是运行应用程序的端系统设备。无线链路。主机通过无线通信链路 (wireless communication link) 连接到一个基站或者另一台无线主机。不同的无线链路技术具有不同的传输速率和能够传输不同的距离。基站。基站在有线网络中没有明确的对应设备。它负责向与之关联的无线主机发送数据和从主机那里接收数据。一台无线主机与某基站“相关联”,则是指①该主机位于该基站的无线通信覆盖范围内。②该主机_移动性代理通告扩展中指出该代理是它所在网络的一个外部代理的字段是

Gradle文件操作基础_gradle ziptree-程序员宅基地

文章浏览阅读1w次。一、定位文件:我们可以使用Project.file()方法来定位一个文件获取File对象(详情参考Project的API),如下://相对路径File configFile = file('src/config.xml')//绝对路径File configFile = file(configFile.absolutePath)//项目路径的文件对象 File config_gradle ziptree

张量分解总览_hooi算法-程序员宅基地

文章浏览阅读2k次,点赞3次,收藏14次。一般一维数组,我们称之为向量(vector),二维数组,我们称之为矩阵(matrix);三维数组以及多位数组,我们称之为张量(tensor)。 在介绍张量分解前,我们先看看矩阵分解相关知识概念。一、基本概念矩阵补全(Matrix Completion)目的是为了估计矩阵中缺失的部分(不可观察的部分),可以看做是用矩阵X近似矩阵M,然后用X中的元素作为矩阵M_hooi算法

随便推点

滥用图片博客做 C&C 配置-程序员宅基地

文章浏览阅读60次。0xCC · 2016/02/03 14:500x00 背景几个月前看到有文章介绍俄罗斯的 Hammertoss 恶意软件,使用 Twitter 作为 C&amp;C 服务。以类似方式滥用 TechNet 的也有过报道【1】。脑洞了一下觉得,使用图片(或者其他格式)作为隐写(steganography)的载体来携带 C&amp;C 控制命令更为隐蔽一些,而且携带的信息容量相对 twitter 的 ..._github c&c

springboot2.0集成activiti6.0-程序员宅基地

文章浏览阅读3.7k次,点赞2次,收藏6次。 activiti6.0直接使用starter集成到springboot2.0时,会报异常,无法直接进行集成。所以我才用spring-activiti来集成activiti6.0.整体文件结构如下:1.pom文件依赖&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.o..._springboot2.0集成activiti6.

国家c语言1级考试题库,国家计算机二级考试 c语言 上机题库100道.docx.docx-程序员宅基地

文章浏览阅读134次。国家计算机二级考试 c语言 上机题库100道.docx1调用fun函数建立班级通讯录,记录学生的编号姓名电话,人数和信息从键盘读入,信息写到myfile5.dat的二进制文件。STYPE FILE fpFun函数先将字符串s中字符按正序存放到t串中,然后把s中字符逆序连到t后. for (i=0;idata t函数fun的功能是:将字符串的字符按逆序输出,但不改变字符串的内容。例,若字符串为..._若传送给m的值为50,则程序输出,7.11.14.21.22.28.33.35.42.44.49,n=11

罗森伯格成功助力安徽省滁州市公安局110指挥中心项目-程序员宅基地

文章浏览阅读183次。安徽省滁州市公安局110指挥中心大楼(含附楼)建筑面积约60000平方米,大楼主要包括指挥中心技术用房、刑侦业务用房、特巡警用房、射击靶场、×××服务大厅、民警训练场、餐厅等,场地景观及附属建筑。建筑主体以办公为主,同时在主体大楼内也规划了公安体系数据中心。 作为整个IT/弱电系统的基础,综合布线系统在此项目中尤其显的重要。通过业主的严密筛...

OS_Sched 函数_os_sched.h-程序员宅基地

文章浏览阅读9.4k次,点赞4次,收藏8次。//任务调度//uCOS-II总是运行进入就绪态任务中优先级最高的那一个。确定哪个任务优先级最高,下面该哪个任务运行了的工作是//由调度器(Scheduler)完成的。任务级的调度是由函数OSSched()完成的。中断级的调度是由另一个函数OSIntExt()完//成的Scheduling。//注意:1) 这是一个uCOS-II内部函数,你不能在应用程序中使用它// 2_os_sched.h

物联网开发笔记(46)- 使用Micropython开发ESP32开发板之控制光敏传感器_esp32光敏传感器-程序员宅基地

文章浏览阅读2k次,点赞3次,收藏24次。使用Micropython开发ESP32开发板之控制光敏传感器_esp32光敏传感器

推荐文章

热门文章

相关标签