/**
* 下载网络地址的图片
* @param downPicUrl 网络地址
* @param user 用户
* @return
*/
public String downloadPicture(String downPicUrl, User user) {
logger.info(user.getAccount() + "用户;网络图片下载的地址" + downPicUrl);
try {
//new一个URL对象
URL url = new URL(downPicUrl);
//打开链接
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
//设置请求方式为"GET"
conn.setRequestMethod("GET");
//超时响应时间为5秒
conn.setConnectTimeout(5 * 1000);
//通过输入流获取图片数据
InputStream inStream = conn.getInputStream();
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
byte[] data = readInputStream(inStream);
//构建文件保存的目录
String fileRealPathDir = UploadUtils.getRealPath(DateUtils.convertDateToString(new Date()));
//获取文件的后缀
String suffix = downPicUrl.substring(downPicUrl.lastIndexOf("."));
String fileName = "";
if (suffix.equalsIgnoreCase(".jpg") || suffix.equalsIgnoreCase(".jpeg") || suffix.equalsIgnoreCase(".png")){
//使用UUID生成文件名称
fileName = SequenceUtils.getUUID() + suffix;//构建文件名称
}else{
//使用UUID生成文件名称
fileName = SequenceUtils.getUUID() + ".jpg";//构建文件名称
}
//拼成完整的文件保存路径加文件
String resultFilePath = fileRealPathDir + "/" + fileName;
//获取网络图片的大小和像素
String size = bytes2kb(data.length);
logger.info("网络图片大小:" + size);
InputStream murl = new URL(downPicUrl).openStream();
BufferedImage sourceImg = ImageIO.read(murl);
int width = sourceImg.getWidth(); // 像素
int height = sourceImg.getHeight(); // 像素
logger.info("网络图片width=" + width + ",网络图片height=" + height + ".");
//图片的尺寸要求是图片大小不超过2M,像素尺寸长宽不超过4096,否则进行压缩
if (size.contains("MB")){
int index = size.indexOf("MB");
String number = size.substring(0,index);
BigDecimal factSize = new BigDecimal(number);
BigDecimal paramSize = new BigDecimal(2);
if (factSize.compareTo(paramSize) > 0 && height < 4096){
//图片以高为标准进行压缩
saveMinPhoto(url, resultFilePath, height, 1);
}else if (factSize.compareTo(paramSize) > 0 && width < 4096){
//图片以宽为标准进行压缩
saveMinPhoto(url, resultFilePath, width, 0);
}else if (factSize.compareTo(paramSize) > 0 && height > 4096 && width > 4096){
//图片以高的一半为标准进行压缩
saveMinPhoto(url, resultFilePath, 2048, 1);
}else if (height >= 4096 && width < 4096){
//图片以宽为标准进行压缩
saveMinPhoto(url, resultFilePath, width, 0);
}else if (height < 4096 && width >= 4096){
//图片以高为标准进行压缩
saveMinPhoto(url, resultFilePath, height, 1);
}else if (height >= 4096 && width >= 4096){
//图片以高的一半为标准进行压缩
saveMinPhoto(url, resultFilePath, 2048, 1);
}else{
File newFile = new File(resultFilePath);
FileCopyUtils.copy(data, newFile);
}
}else if (height >= 4096 && width < 4096){
//图片以宽为标准进行压缩
saveMinPhoto(url, resultFilePath, width, 0);
}else if (height < 4096 && width >= 4096){
//图片以高为标准进行压缩
saveMinPhoto(url, resultFilePath, height, 1);
}else if (height >= 4096 && width >= 4096){
//图片以高的一半为标准进行压缩
saveMinPhoto(url, resultFilePath, 2048, 1);
}else{
File newFile = new File(resultFilePath);
FileCopyUtils.copy(data, newFile);
}
String realPath = UploadUtils.getRelatedPath() + fileName;
//返回路径给页面上传
logger.info(user.getAccount() + "用户;网络照片" + fileName+"下载成功!");
return realPath;
}catch (Exception e){
e.printStackTrace();
logger.info(user.getAccount() + "用户;网络照片,下载异常");
}
return "";
}
//得到图片的二进制数据,以二进制封装得到数据,具有通用性
public byte[] readInputStream(InputStream inStream) throws Exception{
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[1024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
//使用一个输入流从buffer里把数据读取出来
while( (len=inStream.read(buffer)) != -1 ){
//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
//关闭输入流
inStream.close();
//把outStream里的数据写入内存
return outStream.toByteArray();
}
//获取网络图片的大小和像素
public String bytes2kb(long bytes) {
BigDecimal filesize = new BigDecimal(bytes);
BigDecimal megabyte = new BigDecimal(1024 * 1024);
float returnValue = filesize.divide(megabyte, 2, BigDecimal.ROUND_UP)
.floatValue();
if (returnValue > 1)
return (returnValue + "MB");
BigDecimal kilobyte = new BigDecimal(1024);
returnValue = filesize.divide(kilobyte, 2, BigDecimal.ROUND_UP)
.floatValue();
return (returnValue + "KB");
}
/**
* 等比例压缩算法:
* 算法思想:根据压缩基数和压缩比来压缩原图,生产一张图片效果最接近原图的缩略图
* @param srcURL 原图网络地址
* @param deskURL 缩略图地址
* @param comBase 压缩基数
* @param scale 压缩限制(宽/高)比例 一般用1:
* 当scale>=1,缩略图height=comBase,width按原图宽高比例;若scale<1,缩略图width=comBase,height按原图宽高比例
*/
public void saveMinPhoto(URL srcURL, String deskURL, double comBase,
double scale) throws Exception {
Image src = ImageIO.read(srcURL);
int srcHeight = src.getHeight(null);
int srcWidth = src.getWidth(null);
int deskHeight = 0;// 缩略图高
int deskWidth = 0;// 缩略图宽
double srcScale = (double) srcHeight / srcWidth;
/**缩略图宽高算法*/
if ((double) srcHeight > comBase || (double) srcWidth > comBase) {
if (srcScale >= scale || 1 / srcScale > scale) {
if (srcScale >= scale) {
deskHeight = (int) comBase;
deskWidth = srcWidth * deskHeight / srcHeight;
} else {
deskWidth = (int) comBase;
deskHeight = srcHeight * deskWidth / srcWidth;
}
} else {
if ((double) srcHeight > comBase) {
deskHeight = (int) comBase;
deskWidth = srcWidth * deskHeight / srcHeight;
} else {
deskWidth = (int) comBase;
deskHeight = srcHeight * deskWidth / srcWidth;
}
}
} else {
deskHeight = srcHeight;
deskWidth = srcWidth;
}
BufferedImage tag = new BufferedImage(deskWidth, deskHeight, BufferedImage.TYPE_3BYTE_BGR);
tag.getGraphics().drawImage(src, 0, 0, deskWidth, deskHeight, null); //绘制缩小后的图
FileOutputStream deskImage = new FileOutputStream(deskURL); //输出到文件流
saveAsJPEG(tag, deskImage);
deskImage.close();
}
/**
* 以JPEG编码保存图片
* @param image_to_save 要处理的图像图片
* @param fos 文件输出流
* @throws IOException
*/
public static void saveAsJPEG(BufferedImage image_to_save,FileOutputStream fos) throws IOException {
ImageWriter imageWriter = ImageIO.getImageWritersBySuffix("jpg").next();
ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
imageWriter.setOutput(ios);
IIOMetadata imageMetaData = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(image_to_save), null);
imageWriter.write(imageMetaData, new IIOImage(image_to_save, null, null), null);
ios.close();
imageWriter.dispose();
}