/**
* 根据指定大小压缩图片
*
* @param imageBytes 源图片字节数组
* @param desFileSize 指定图片大小,单位kb
* @param imageId 影像编号
* @return 压缩质量后的图片字节数组
*/
public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize, String imageId) {
if (imageBytes == null || imageBytes.length <= 0 || imageBytes.length < desFileSize * 1024) {
return imageBytes;
}
long srcSize = imageBytes.length;
double accuracy = getAccuracy(srcSize / 1024);
try {
while (imageBytes.length > desFileSize * 1024) {
ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(imageBytes.length);
Thumbnails.of(inputStream)
.scale(accuracy)
.outputQuality(accuracy)
.toOutputStream(outputStream);
imageBytes = outputStream.toByteArray();
}
log.info("【图片压缩】imageId={" + imageId + "} | 图片原大小={" + srcSize / 1024 + "}kb | 压缩后大小={" + imageBytes.length / 1024 + "}kb");
} catch (Exception e) {
log.error("【图片压缩】msg=图片压缩失败!", e);
}
return imageBytes;
}
/**
* 自动调节精度(经验数值)
*
* @param size 源图片大小
* @return 图片压缩质量比
*/
private static double getAccuracy(long size) {
double accuracy;
if (size < 900) {
accuracy = 0.85;
} else if (size < 2047) {
accuracy = 0.6;
} else if (size < 3275) {
accuracy = 0.44;
} else {
accuracy = 0.4;
}
return accuracy;
}
/**
* 压缩图片
*
* @param picUrl 图片url
* @param size 单位kb
* @return 新图片url
*/
public static String zipPic(String picUrl, Integer size) throws Exception {
URL url = new URL(picUrl);
//打开链接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置请求方式为"GET"
conn.setRequestMethod("GET");
//超时响应时间为5秒
conn.setConnectTimeout(5 * 1000);
//通过输入流获取图片数据
InputStream inStream = conn.getInputStream();
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
byte[] bytes = readInputStream(inStream);
BigDecimal fileSize = new BigDecimal(bytes.length);
BigDecimal kilobyte = new BigDecimal(1024);
float returnValue = fileSize.divide(kilobyte, 2, BigDecimal.ROUND_UP).floatValue();
if (returnValue <= size) {
return picUrl;
}
//少于指定size
bytes = compressPicForScale(bytes, size, "x");
InputStream inputStream = new ByteArrayInputStream(bytes);
// 拿到 inputStream 怎么保存都可以啦 - 这里是上传到阿里云oss
Map<String, Object> result = OssFileUtils.upload(IDUtils.nextIdText() + ".jpg", inputStream);
String newUrl = result.get("filePath").toString();
return newUrl;
}
/**
* 压缩本地图片,给本地
* @param picUrl 本地图片url
* @param size 单位kb
* @return 本地图片url
*/
public static String zipPicPC(String picUrl, Integer size) throws Exception {
File file = new File(picUrl);
//通过输入流获取图片数据
InputStream inStream = new FileInputStream(file);
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
byte[] bytes = readInputStream(inStream);
BigDecimal fileSize = new BigDecimal(bytes.length);
BigDecimal kilobyte = new BigDecimal(1024);
float returnValue = fileSize.divide(kilobyte, 2, BigDecimal.ROUND_UP).floatValue();
if (returnValue <= size) {
return picUrl;
}
//少于指定size
bytes = compressPicForScale(bytes, size, "x");
InputStream inputStream = new ByteArrayInputStream(bytes);
inputstreamtofile(inputStream, file);
return file.getPath();
}
public static void inputstreamtofile(InputStream ins, File file) throws Exception {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
}