2014年5月23日

圖片的base64編碼與解碼

client要將檔案以http protocol傳上server有許多方式,除了一般普遍使用的multipart/form-data外本文介紹將圖檔以base64編成字串後再傳遞的方式。

base64編碼與解碼需借助apache common codec library

圖片轉成byte需借助ImageIO

程式碼如下

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.apache.commons.codec.binary.Base64;

public class TestBase64 {
    public static void main(String[] args) {
        try {
            // 將檔案透過imageio轉成byte
            String filename = "/Users/james/Downloads/IMAGE_1.jpg";
            BufferedImage img = ImageIO.read(new File(filename));
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            ImageIO.write(img, "jpg", bos);
            byte[] imageBytes = bos.toByteArray();
            bos.close();

            // 將byte執行編碼
            String imageString = Base64.encodeBase64String(imageBytes);

            // 印出編碼結果
            System.out.println("length=" + imageString.length());
            System.out.println("string=" + imageString);

            // 再將編碼後的字串轉成圖檔
            String filename_2 = "/Users/james/Downloads/IMAGE_2.jpg";
            BufferedImage bufferedImage = null;

            byte[] imageByte = Base64.decodeBase64(imageString);
            ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
            bufferedImage = ImageIO.read(bis);
            bis.close();

            ImageIO.write(bufferedImage, "jpg", new File(filename_2));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

經過測試後原本IMAGE_1的圖檔size為1.1MB,經過BASE64編解碼、ImageIO讀寫後IMAGE_2的size居然縮小為440k。經過進一步比較後,後者的檔案exif會遺失,圖片品質的話看不出有明顯的改變。檔案變小的問題應該是在ImageIO。如果要維持原檔不變的話可試試別種libray將圖檔轉成byte。