最近遇到一个问题,要求是在把一张存在于网络上的图片进行下载和压缩。
解决思路:
1、获取图片的输入流
2、得到图片的字节流
3、使用google的thumbnailator.jar对字节流进行压缩
4、把压缩后的字节流重新转换为输入流
5、设置下载地址,下载到本地或ftp服务器
实现
这里只介绍下载到本地的具体实现方式
我才用的是Spring boot + maven搭建的测试项目
首先要引入google的thumbnailator的引用
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
构建图片压缩转换的工具类
import net.coobird.thumbnailator.Thumbnails;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
/**
* 文件处理工具类
*
*/
public class UploadUtils {
/**
* 从输入流中获取数据
* @param inStream
* @return
* @throws Exception
*/
public static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
inStream.close();
return outStream.toByteArray();
}
/**
* 根据指定大小压缩图片
*
* @param imageBytes 源图片字节数组
* @param desFileSize 指定图片大小,单位kb
* @return 压缩质量后的图片字节数组
*/
public static byte[] compressPicForScale(byte[] imageBytes, long desFileSize) {
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();
}
System.out.println("【图片压缩】| 图片原大小={" + srcSize / 1024 + "}kb | 压缩后大小={" + imageBytes.length / 1024 + "}kb | ");
} catch (Exception e) {
System.out.println("【图片压缩】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;
}
}
编写测试方法
public static void main(String[] args) throws Exception {
//这里同样用File获取一下文件,便于拿到文件的名称、类型等信息
File file = new File(imageUrl);
//http://xxx/xxx/xxx.png(jpg等等)
URL url = new URL("完整图片地址");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
//通过输入流获取图片数据
InputStream urlInputStream = conn.getInputStream();
//获取图片的字节流
byte[] imgBytes = readInputStream(urlInputStream);
//压缩图片
byte[] minImgBytes = compressPicForScale(imgBytes, 40);
//将压缩后的字节流转换为输入流
InputStream inputStream = new ByteArrayInputStream(minImgBytes);
//获取图片字节流并写入磁盘
outputStreamFile(readInputStream(inputStream), "20190426095107749847010.png");
//上传文件到ftp(FTPUtils:自定义ftp工具类)
//String uploadFilePath = FTPUtils.uploadFile("20190426095107749847010.png", filePath, inputStream);
}
网友评论