运行平台: windows10
JDK版本: 1.8
IDE: eclipse
一. 知识储备
Java IO流 :
本文用到的IO方法:
DataInputStream;
BufferedInputStream;
FileOutputStream;
BufferedOutputStream;
BufferedImage类:
简单地说,BufferedImage类是一个能够操作图片的类。类似文件流,BufferedImage以图片流的形式进行各种操作,它是Image的子类。官方API链接
使用到的方法:
- BufferedImage.createGraphics():创建一个能被写进BufferedImage里的图像类Graphics2D
- Graphics.drawImage(Image img, int x, int y, int width, int height, ImageObserver observer):该方法将图片 img,依照给定的width/height生成压缩后的图片,写入Graphics.
ImageIO类:
一个便于图片读写,并能够进行简单编码解码的静态类.
官方API链接
二. 代码思路
- 根据url从服务器获取到原图,保存到缓存中
- 获取url的输入流 dataInputStream
- 构造BufferedInputStream来优化读写效率
- 构造原始图片流 preImage
- 确定压缩比例
- 获得原始图片的长宽 width/height
- 定义压缩比例为原来的1/2
- 根据压缩比例,按照原图绘制出压缩后的新图
- 构造压缩后的图片流 image 长宽各为原来的1/2
- 给图片流image创建Graphics ,在Graphics上绘制压缩后的图片
- 将新图写入文件,保存到磁盘
- file生成对应的文件输出流,并将image传给输出流
- 将image写入到file中
- 关闭输入输出流
三. 具体实现
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
public class CompressedImageDownload {
public static void main(String[] args) {
String pathname="test.gif";//
File file=new File(pathname);
String urlstr="https://www.baidu.com/img/baidu_jgylogo3.gif";//此处为指定指定图片的url,以百度logo为例
boolean success=false;
success=downloadCompressedPicture(file, urlstr);
System.out.println(success?"success":"false");
}
/**
* url下载压缩图
* jdk1.8可以执行
* jdk1.4无法执行
* @param file
* @param urlstr
* @return
*/
public static boolean downloadCompressedPicture(File file,String urlstr){
URL url=null;
try{
url=new URL(urlstr);
//1.获取url的输入流 dataInputStream
DataInputStream dataInputStream=new DataInputStream(url.openStream());
//2.加一层BufferedInputStream
BufferedInputStream bufferedInputStream=new BufferedInputStream(dataInputStream);
//3.构造原始图片流 preImage
BufferedImage preImage=ImageIO.read(bufferedInputStream);
//4.获得原始图片的长宽 width/height
int width=preImage.getWidth();
int height=preImage.getHeight();
//5.构造压缩后的图片流 image 长宽各为原来的1/2
BufferedImage image=new BufferedImage(width/2, height/2, BufferedImage.TYPE_INT_RGB);
//6.给image创建Graphic ,在Graphic上绘制压缩后的图片
Graphics graphic=image.createGraphics();
graphic.drawImage(preImage, 0, 0, width/2, height/2, null);
//7.为file生成对应的文件输出流
//将image传给输出流
FileOutputStream fileOutputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(fileOutputStream);
//8.将image写入到file中
ImageIO.write(image, "bmp", bufferedOutputStream);
//9.关闭输入输出流
bufferedInputStream.close();
bufferedOutputStream.close();
return true;
}catch(IOException e){
System.out.println(e);
}
return false;
}
}
四. 总结
比较坑爹的是 ImageIO在jdk1.4中无法正确写出到磁盘中。因为公司里有个老项目用的是jdk1.4虽然最后使用了JPEGImageEncoder
方法绕过了这个问题,但还是忍不住吐槽一下。都是jdk1.8的时代了,竟然还不淘汰jdk1.4 =。=