1. 程式人生 > >Java圖片合成、base64轉換

Java圖片合成、base64轉換

主要是工作中用到要將客戶上傳的身份證正反面照片從資料庫中取出來(格式為base64字串,竟然是將圖片儲存在資料庫裡面的),合成成為一張圖片,然後再轉碼為base64,呼叫第三方介面把合成圖片的base64傳過去。(後面就不知道他們拿去幹什麼了)

  • 圖片合成
參考: 使用Java合併圖片 ,寫了一個圖片合成的例子,可以優化的地方還有很多。僅供參考。
圖片尺寸縮放(壓縮),網上很多都是使用老版本的 JPEGImageEncoder類的方法,這個方法是sun公司私有方法,IDE沒有設定的話可能找不到這個類。現在採用的是ImageIO類的方法,可以正常輸出圖片。
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class CompositePhotograph
{
/**
* @描述: 合成圖片
* @param face 身份證正面
* @param back 身份證反面
* @param fileName 合成圖片檔名
* @return
* @throws IOException
*/
public static File compositePhoto(File face , File back ,String fileName) throws IOException{
BufferedImage b1 = ImageIO.read(face);
BufferedImage b2 = ImageIO.read(back);
//根據兩張圖片得到合成圖片的寬高
int width = b1.getWidth()<b2.getWidth() ? b1.getWidth() : b2.getWidth();
int height = b1.getHeight() + b2.getHeight();
//合成的圖片
BufferedImage cp = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = cp.getGraphics();
g.drawImage(b1,0,0,null);//上部分
g.drawImage(b2,0,b1.getHeight(),null);//下部分
//檢查檔案
File f = new File(fileName);
if(f.exists()){
f.delete();
f.createNewFile();
}else{
f.createNewFile();
}
//輸出圖片
ImageIO.write(cp, "jpg", f);
return f;
}

/**
* @描述: 改變圖片尺寸,按給出的width,等比例縮放高
* @param bi 需要改變的圖片
* @param fileName 生成的新圖片的檔名
* @param width 修改的寬
* @return
* @throws IOException
*/
public static File resize(File source,String fileName,int width) throws IOException{
Image img = ImageIO.read(source);//原圖片檔案
int srcW = img.getWidth(null);
int srcH = img.getHeight(null);
double x = (double)width/(double)srcW;//縮放比例
int height = (int) (srcH * x);//縮放後的高
//新圖片
BufferedImage newImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//縮放後的圖片
Image tag = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);
newImg.getGraphics().drawImage(tag, 0, 0, null);//繪製到畫板上
File f = new File(fileName);
if(f.exists()){
f.delete();
f.createNewFile();
}else{
f.createNewFile();
}
/* 輸出到檔案流 ,網上很多都是這種寫法,這是已經過時了的寫法,現在都使用ImageIO.write()來輸出壓縮後的檔案了
FileOutputStream out = new FileOutputStream(f);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(tag);
out.flush();
out.close();
*/
//寫入檔案
ImageIO.write(newImg, "jpg", f);
return f;
}
}



  • base64編碼轉換
在讀取BufferedInputStream輸入流的內容的時候,使用了這個byte[] bytes = new byte[bis.available()];bis.read(bytes);一次性將檔案內容全部讀取出來。之前試過使用while( (count=bis.read(bytes)) != -1 ){ strBuilder.append(bytes); }來分步讀取,但是讀取出來的結果不對,也沒有去探究原因//TODO 待查吧。
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

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

public class DENcode
{
//讀寫尺寸
private final static int SIZE = 1024*10;

/**
* @描述: 將檔案編碼為base64格式
* @param f 要編碼的檔案
* @return
* @throws IOException
*/
public String encode(File f) throws IOException{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));//將檔案轉換成流
byte[] bytes = new byte[bis.available()];//記錄二進位制陣列,大小為bis讀取不阻塞長度
bis.read(bytes);//一次性全部讀取
bis.close();
Base64 b = new Base64();
byte[] encodeFile = b.encode(bytes);//編碼
return new String(encodeFile);
}

/**
* @描述: 將base64解碼為圖片檔案
* @param base64Str base64編碼字串
* @param fileName 轉換成的圖片檔名
* @return
* @throws DecoderException
* @throws IOException
*/
public File decode(String base64Str,String fileName) throws DecoderException, IOException{
//使用apache的編解碼類
Base64 b = new Base64();
byte[] by = b.decode(base64Str);
//調整異常資料
for(int i=0;i<by.length;++i){
if(by[i]<0){
by[i]+=256;
}
}
File df = new File(fileName);
//刪除舊檔案,防止寫入時有垃圾資料
if(df.exists()){
df.delete();
}else{
df.createNewFile();
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(df),SIZE);
bos.write(by);
bos.flush();
bos.close();
return df;
}

}



  • 一個小demo,實現前面的業務邏輯

import java.io.File;
import java.io.IOException;

import org.apache.commons.codec.DecoderException;

import composite_photograph.CompositePhotograph;
import ende_code.DENcode;

public class Photograph
{
public static void main(String[] args) throws DecoderException, IOException
{
System.out.println("開始");

String fan = "base64字串1";

String zheng = "base64字串2";

DENcode denCode = new DENcode();
File fanF = denCode.decode(fan, "resources/fan.jpg");
File zhengF = denCode.decode(zheng, "resources/zheng.jpg");
File reFanF = CompositePhotograph.resize(fanF, "resources/reFan.jpg", 500);
File reZhengF = CompositePhotograph.resize(zhengF, "resources/reZheng.jpg", 500);
File cpF = CompositePhotograph.compositePhoto(reZhengF, reFanF,"resources/cp.jpg");
String cpStr = denCode.encode(cpF);
System.out.println("完成");
}
}