1. 程式人生 > >Java 從網頁指定url獲取圖片並壓縮到本地

Java 從網頁指定url獲取圖片並壓縮到本地

執行平臺: windows10
JDK版本: 1.8
IDE: eclipse

一. 知識儲備

Java IO流 :
  推薦部落格: Java IO詳解
  本文用到的IO方法:

DataInputStream;
BufferedInputStream;
FileOutputStream;
BufferedOutputStream;

BufferedImage類:
  簡單地說,BufferedImage類是一個能夠操作圖片的類。類似檔案流,BufferedImage以圖片流的形式進行各種操作,它是Image的子類。官方API連結
使用到的方法:

  1. BufferedImage.createGraphics():建立一個能被寫進BufferedImage裡的影象類
    Graphics2D
  2. Graphics.drawImage(Image img, int x, int y, int width, int height, ImageObserver observer):該方法將圖片 img,依照給定的width/height生成壓縮後的圖片,寫入Graphics.

ImageIO類:
  一個便於圖片讀寫,並能夠進行簡單編碼解碼的靜態類.
  官方API連結

二. 程式碼思路

  1. 根據url從伺服器獲取到原圖,儲存到快取中
    1. 獲取url的輸入流 dataInputStream
    2. 構造BufferedInputStream來優化讀寫效率
    3. 構造原始圖片流 preImage

  2. 確定壓縮比例
    1. 獲得原始圖片的長寬 width/height
    2. 定義壓縮比例為原來的1/2

  3. 根據壓縮比例,按照原圖繪製出壓縮後的新圖
    1. 構造壓縮後的圖片流 image 長寬各為原來的1/2
    2. 給圖片流image建立Graphics ,在Graphics上繪製壓縮後的圖片

  4. 將新圖寫入檔案,儲存到磁碟
    1. file生成對應的檔案輸出流,並將image傳給輸出流
    2. 將image寫入到file中
    3. 關閉輸入輸出流

三. 具體實現

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 =。=