目录
1. 引入pom依赖
- 谷歌压缩工具Thumbnailator, 支持 图片缩放,区域裁剪,水印,旋转等
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
</parent>
<dependencies>
<!--两个用来做测试的jar包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!--主要的图片处理对象-->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.14</version>
</dependency>
</dependencies>
2. 配置常量枚举
- 这里主要是为了规范,测试的话写个常量就行
public enum ImgSizes {
/**
* 小图100*100
*/
_100_100{
@Override
public int height(){
return 100;
}
/**
* 图片宽度
*/
@Override
public int width() {
return 100;
}
/**
* 名称
*/
@Override
public String sizeName(){
return "100_100小图";
}
},
_200_300{
@Override
public int height(){
return 300;
}
/**
* 图片宽度
*/
@Override
public int width() {
return 200;
}
/**
* 名称
*/
@Override
public String sizeName(){
return "200_300规格图";
}
},
/**
* 大图400*400
*/
_400_400{
@Override
public int height(){
return 400;
}
/**
* 图片宽度
*/
@Override
public int width() {
return 400;
}
/**
* 名称
*/
@Override
public String sizeName(){
return "400_400大图";
}
};
/**
* 图片长度
*/
public abstract int height();
/**
* 图片宽度
*/
public abstract int width();
/**
* 图片别名
* @return
*/
public abstract String sizeName();
}
3. Thumbnailator常用方法解析介绍
原图:
原图参数:
3.1 size(int var1, int var2):指定大小进行缩放
- size(width,height) 若图片横比入参小,高比入参小,图片大小不变
- toOutputStream(OutputStream var1): 直接获取字节流等参数
- keepAspectRatio(boolean var1): 是否强制指定大小进行缩放 (默认为false)
import com.it.mhh.enums.ImgSizes;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
public class thumbnailatorTest {
/*
*todo():
* 反参:toOutputStream(OutputStream var1): 直接获取字节流等参数
* 反参:toFile(File var1 || String var1): 直接写出比例图片
* 参数:keepAspectRatio(boolean var1): 是否强制指定大小进行缩放 (),false表示强制指定大小进行缩放
*
* size(width,height) 若图片横比200小,高比300小,不变
* 若图片横比200小,高比300大,高缩小到300,图片比例不变 若图片横比200大,高比300小,横缩小到200,图片比例不变
* 若图片横比200大,高比300大,图片按比例缩小,横为200或高为300
*/
@Test
public void toOutputStreamTest() throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// Thumbnails.of("D:\\doc\\FF.jpg").size(ImgSizes._100_100.length(),ImgSizes._100_100.width()).toFile("D:\\doc\\100.jpg");
Thumbnails.of("D:\\doc\\FF.jpg").size(ImgSizes._200_300.height(), ImgSizes._200_300.width()).keepAspectRatio(false).toOutputStream(outputStream);
ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("D:\\doc\\new.jpg"));
int len;
byte[] bytes = new byte[128];
while ((len = inputStream.read(bytes)) != -1) {
bufferedOutputStream.write(bytes, 0, len);
}
bufferedOutputStream.close();
inputStream.close();
}
}
结果:
- 可以看到 因为设置了keepAspectRatio(boolean var1)并制定了false 所以按强制性自己规定的像素,其实这里不建议强制性 会造成图片像素看着不协调,扭曲;
3.2 scale(double var1, double var3):按照比列进行缩放或扩大
- 缩放还是扩大改变的都是像素
- scale(double var1 || double var1, double var3):传一个参表示按此比例进行缩放或者扩大;两个参则表示(宽度,高度)缩放或扩大
>1为扩大 <1为缩放
import com.it.mhh.enums.ImgSizes;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
public class thumbnailatorTest {
/**
* todo() 改变的是像素
* scale(double var1 || double var1, double var3):传一个参表示按此比例进行缩放或者扩大;两个参则表示(宽度,高度)缩放或扩大 >1为扩大 <1为缩放
* <p>
* 按照比例进行缩放
*
* @throws IOException
*/
@Test
public void scaleTest() throws IOException {
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(new File("D:\\doc\\FF.jpg")));
//Thumbnails.of(bufferedInputStream).scale(2).toFile("D:\\doc\\scale.jpg");
//宽度,高度
Thumbnails.of(bufferedInputStream).scale(1, 2).toFile("D:\\doc\\scale.jpg");
}
}
结果:
- 可以看出我只是在 高度上填了2 所以只是高度是扩大 2倍
3.3 rotate(double var1):旋转
- rotate(角度):
正数:顺时针 负数:逆时针
- URL:(file:) 表示获取本地文件
import com.it.mhh.enums.ImgSizes;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
public class thumbnailatorTest {
/*
* todo()
* 旋转:
* rotate(角度);
* 正数:顺时针 负数:逆时针
* URL:(file:\) 表示获取本地文件
*
* */
@Test
public void rotateTest() throws IOException {
//URL:(file:\) 表示获取本地文件
URL url = new URL("file:\\D:\\doc\\FF.jpg");
// rotate(角度),正数:顺时针 负数:逆时针
Thumbnails.of(url).scale(1).rotate(180).toFile("D:\\doc\\rotate.jpg");
}
}
结果:
- 填的是正数…这里是顺时针旋转得出的结果 虽然旋转了180°看不出来…
3.4 watermark(Position var1, BufferedImage var2, float var3):添加水印
水印:
- watermark(水印位置,要添加的水印图,透明度)
- 水印透明度取值范围[0f-1f]
- outputQuality(图片质量) 取值范围[0f-1f]
import com.it.mhh.enums.ImgSizes;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
public class thumbnailatorTest {
/**
* TODO()
* watermark(水印位置,要添加的水印图,透明度)
* 水印透明度取值范围[0f-1f]
* outputQuality(图片质量)
* 取值范围[0f-1f]
*/
@Test
public void watermarkTest() throws IOException {
// watermark(水印位置,要添加的水印图,透明度)
Thumbnails.of("D:\\doc\\FF.jpg").scale(1).watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("D:\\doc\\aa.png")), 0.5f)
.outputQuality(1f).useOriginalFormat().toFile("D:\\doc\\watermark.jpg");
}
}
结果:
- 可指定水印添加在哪个位置以及水印的透明度[取值范围(0F-1F)]
3.5 sourceRegion(Position var1, int var2, int var3):剪裁
- java中
Positions
定位枚举 不多说 就是上中下 左右 等…- 主要说下
自定义剪裁
:sourceRegion(int var1, int var2, int var3, int var4) va1确定其宽度 va2确定其高度 va1和va2确定一个点 va3为宽度 va4为高度 va1+va3为第二个点的宽度 va2+va4为顶二个点的高度 两个点确定剪裁范围
import com.it.mhh.enums.ImgSizes;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
public class thumbnailatorTest {
/**
* TODO()
* 裁剪
* 自定义裁剪范围:
* //sourceRegion(int var1, int var2, int var3, int var4) va1确定其宽度 va2确定其高度 va1和va2确定一个点 va3为宽度 va4为高度 va1+va3为第二个点的宽度 va2+va4为顶二个点的高度 两个点确定剪裁范围
*
* @throws IOException
*/
@Test
public void sourceRegionTest() throws IOException {
/**
* 图片中心400*400的区域
*/
Thumbnails.of("D:\\doc\\FF.jpg").scale(1).sourceRegion(Positions.CENTER, ImgSizes._400_400.height(), ImgSizes._400_400.width()).toFile("D:\\doc\\centerSourceRegion.jpg");
/**
* 图片右下400*400的区域
*/
Thumbnails.of("D:\\doc\\FF.jpg").scale(1).sourceRegion(Positions.BOTTOM_RIGHT, ImgSizes._400_400.height(), ImgSizes._400_400.width()).toFile("D:\\doc\\bottomRightSourceRegion.jpg");
/**
* 指定坐标
*///sourceRegion(int var1, int var2, int var3, int var4) va1确定其宽度 va2确定其高度 va1和va2确定一个点 va3为宽度 va4为高度 va1+va3为第二个点的宽度 va2+va4为顶二个点的高度 两个点确定剪裁范围
Thumbnails.of("D:\\doc\\FF.jpg").scale(1).sourceRegion(50, 0, 700, 550).toFile("D:\\doc\\sourceRegion.jpg");
}
}
自定义剪裁结果:
- 自定义剪裁 用4个值确定两个点
3.6 outputFormat(String var1):转化图像格式
- outputFormat(String var1): 其实这里也可以不用这个方法 只要指定后缀名就可以 什么样的后缀名就是什么格式
import com.it.mhh.enums.ImgSizes;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
public class thumbnailatorTest {
/**
* todo()
* 转化图像格式
* outputFormat(String var1): 其实这里也可以不用这个方法 只要指定后缀名就可以 什么样的后缀名就是什么格式
*
* @throws IOException
*/
@Test
public void outputFormatTest() throws IOException {
/**
* outputFormat(图像格式)
*/
Thumbnails.of("D:\\doc\\FF.jpg").scale(1).outputFormat("gif").toFile("D:\\doc\\outputFormat.gif");
}
}
结果:
- 从jpg格式转换为 gif格式
3.7 反参:BufferedImage
- 获取带缓冲区图像类
import com.it.mhh.enums.ImgSizes;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
public class thumbnailatorTest {
/**
* 输出到BufferedImage
*
* @throws IOException
*/
@Test
public void asBufferedImageTest() throws IOException {
/**
* asBufferedImage() 返回BufferedImage
*/
BufferedImage thumbnail = Thumbnails.of("D:\\doc\\FF.jpg").scale(1).asBufferedImage();
ImageIO.write(thumbnail, "jpg", new File("D:\\doc\\imageIO.jpg"));
}
}
结果:
- 通过获得BufferedImage对象 通过ImageIO对象写出
javax.imageio.IIOException: Unsupported Image Type 异常解决:
- 引入下方依赖就可以了
- 该工具类用于java代码ImageIO.read()的文件为jpg格式,且色彩模式为cmyk格式时抛异常Unsupported Image Type 可以导入该工具类,代码不需要加任何处理,再次运行即可。
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-jpeg</artifactId>
<version>3.4.1</version>
</dependency>