上篇我们讲了文件的上传,一般图片上传都会有压缩图,并且有水印,防止图片被非法使用,这篇我们就讲图片的压缩与添加水印。网上很多压缩与添加水印的工具,我们使用thumbnailator。
添加相关依赖
<!--使用thumbnailator依赖包(图片压缩)-->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.2</version>
</dependency>
简单的图片压缩
//size(宽度, 高度)
/*
* 若图片横比200小,高比300小,不变
* 若图片横比200小,高比300大,高缩小到300,图片比例不变
* 若图片横比200大,高比300小,横缩小到200,图片比例不变
* 若图片横比200大,高比300大,图片按比例缩小,横为200或高为300
*/
Thumbnails.of("images/a380_1280x1024.jpg")
.size(200, 300)
.toFile("c:/a380_200x300.jpg");
Thumbnails.of("images/a380_1280x1024.jpg")
.size(2560, 2048)
.toFile("c:/a380_2560x2048.jpg");
简单的添加水印
//watermark(位置,水印图,透明度)
Thumbnails.of("images/a380_1280x1024.jpg")
.size(1280,1024)
.watermark(Positions.BOTTOM_RIGHT,ImageIO.read(newFile("images/watermark.png")),0.5f)
.outputQuality(0.8f)
.toFile("c:/a380_watermark_bottom_right.jpg");
Thumbnails.of("images/a380_1280x1024.jpg")
.size(1280,1024)
.watermark(Positions.CENTER,ImageIO.read(newFile("images/watermark.png")),0.5f)
.outputQuality(0.8f)
.toFile("c:/a380_watermark_center.jpg");
公司使用的是fastdfs,因此没有实体图片,会稍微复杂一些,接上篇,图片上传工具类就是把上篇的图片上传代码封装为一个工具类,同时图片压缩需要一个图片实体,因此这里是直接在根目录生成,压缩与添加水印后删除,代码如下:
package com.qivay.util;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Administrator on 2017-11-07.
* 图片压缩工具类
*/
public class ImageCompressUtil {
/**
* 图片压缩
* @param bytes 文件转换的字节流
* @param name 文件名
* @param width 压缩后宽度
* @param helper 图片上传工具类
* @param needWatermark 是否需要水印
* @return
* @throws Exception
*/
public static String[] compress(byte[] bytes, String name, int width, FastDFSHelper helper, boolean needWatermark) throws Exception {
File directory = new File("");//参数为空
String courseFile = directory.getCanonicalPath();
File file = new File(courseFile, name);
OutputStream output = new FileOutputStream(file);
BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);
bufferedOutput.write(bytes);
bufferedOutput.close();
output.close();
//获取原图的高和宽
int imgWidth = getImgWidth(file);
int imgHeight = getImgHeight(file);
//设置对应的高度
int height = width * imgHeight / imgWidth;
int index = name.lastIndexOf(".");
String suffix = name.substring(index);
String fileName = UUIDHelper.GetUUID() + suffix;
File newFile = new File(courseFile, fileName);
//设置水印
String compressImage = setWatermark(needWatermark, courseFile, width, height, file, newFile, helper);
String normalImage = "";
if (needWatermark) {
String normalName = UUIDHelper.GetUUID() + suffix;
File normalFile = new File(courseFile, normalName);
normalImage = setWatermark(needWatermark, courseFile, getImgWidth(file), getImgHeight(file), file, normalFile, helper);
normalFile.delete();
} else {
normalImage = getFastdfsUrl(file, helper);
}
newFile.delete();
file.delete();
return new String[]{normalImage, compressImage};
}
/**
* 设置水印
*/
private static String setWatermark(boolean needWatermark, String courseFile, int width, int height, File file, File newFile, FastDFSHelper helper) throws Exception {
if (needWatermark) {
//获取水印图
File path = new File(ImageCompressUtil.class.getResource("/static/image/qivay.png").getPath());
File watermark = new File(path.getPath());
double watermarkWidth = getImgWidth(watermark);
double watermarkHeight = getImgHeight(watermark);
//获取同样3/4大小的水印图
File newWatermark = new File(courseFile, "qivay.png");
double proportion = watermarkWidth / watermarkHeight;
watermarkWidth = width * 3 / 4;
watermarkHeight = new Double(watermarkWidth / proportion).intValue();
if (height * 3 / 4 < watermarkHeight) {
watermarkHeight = height * 3 / 4;
watermarkWidth = new Double(watermarkHeight * proportion).intValue();
}
Thumbnails.of(watermark.getPath())
.forceSize(new Double(watermarkWidth).intValue(), new Double(watermarkHeight).intValue())
.outputQuality(ConstantUtil.IMAGE_MULTIPLE)
.toFile(newWatermark.getPath());
Thumbnails.of(file.getPath())
.forceSize(width, height)
.watermark(Positions.CENTER, ImageIO.read(newWatermark), 0.5f)
.outputQuality(ConstantUtil.IMAGE_MULTIPLE)
.toFile(newFile.getPath());
newWatermark.delete();
} else {
Thumbnails.of(file.getPath())
.forceSize(width, height)
.outputQuality(ConstantUtil.IMAGE_MULTIPLE)
.toFile(newFile.getPath());
}
return getFastdfsUrl(newFile, helper);
}
/**
* 获取图片上传到fastdfs上的url
*
* @param newFile
* @param helper
* @return
* @throws IOException
*/
private static String getFastdfsUrl(File newFile, FastDFSHelper helper) throws IOException {
StringBuilder sb = new StringBuilder();
String[] ids = null;
FileInputStream fileInputStream = new FileInputStream(newFile);
byte[] fileBytes = helper.inputStreamToBytes(fileInputStream);
ids = helper.upload(fileBytes, newFile.getName());
if (ids.length == 2) {
sb.append("/" + ids[0] + "/");
sb.append(ids[1]);
}
fileInputStream.close();
return sb.toString();
}
/**
* 压缩图片,根据上传得到的文件
*
* @param mf
* @param width
* @param helper
* @return
* @throws Exception
*/
public static String[] compressFile(MultipartFile mf, int width, FastDFSHelper helper, boolean needWatermark) throws Exception {
byte[] bytes = mf.getBytes();
return compress(bytes, mf.getOriginalFilename(), width, helper, needWatermark);
}
/**
* 获取图片宽度
*
* @param file 图片文件
* @return 宽度
*/
public static int getImgWidth(File file) {
InputStream is = null;
BufferedImage src = null;
int ret = -1;
try {
is = new FileInputStream(file);
src = ImageIO.read(is);
ret = src.getWidth(); // 得到原图宽
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
/**
* 获取图片高度
*
* @param file 图片文件
* @return 高度
*/
public static int getImgHeight(File file) {
InputStream is = null;
BufferedImage src = null;
int ret = -1;
try {
is = new FileInputStream(file);
src = javax.imageio.ImageIO.read(is);
ret = src.getHeight(); // 得到源图高
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
}
更多thumbnailator应用https://www.xuebuyuan.com/3229489.html。