2018-06-15: Java 將網絡圖片SRC轉換爲Base64, Base64轉 MultipartFile

---------------------------------- BEGIN ---------------------------------java

背景: 項目須要,不一樣服務器之間圖片截圖互傳,JS new Image() 涉及到跨域問題,於安全考慮,禁用服務器跨域,因而週轉了以下解決方案。web

具體邏輯:
java 後臺 根據圖片SRC獲取圖片Base64編碼供前臺顯示, 前臺 JS 操做(裁剪、截圖,前面文章有具體方法 JS 自定義 截圖、裁剪), 完成後將Base64字符串傳到後臺,後臺解碼生成MultipartFile ...spring

一、先上 公共的文件處理類 WebFileUtilsjson

package com.aaa.bbb.ccc.ddd.helper;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.util.Base64;

/**
 * @Function : 圖片處理幫助類 - 把URL裏的圖片導入到本地 - 將IMG的SRC地址轉爲File - base64編碼圖片轉 MultipartFile
 * @Author & @Date : lynn_ - 2018年06月15日
 */
@Service("webFileUtils")
public class WebFileUtils {

/**
 * 臨時文件位置
 */
private static String tempFilePath = "";

/**
 * 根據url拿取file
 * 
 * @param url
 * @param suffix - 文件後綴名
 */
public static File createFileByUrl(String url, String suffix) {
	byte[] byteFile = getImageFromNetByUrl(url);
	if (byteFile != null) {
		File file = getFileFromBytes(byteFile, suffix);
		return file;
	} else {
		System.out.println("生成文件失敗!");
		return null;
	}
}

/**
 * @Function: 建立臨時文件
 * @param byteFile
 * @param suffix
 */
private static File getFileFromBytes(byte[] byteFile, String suffix) {
	BufferedOutputStream stream = null;
	File file = null;
	try {
		//注意這裏的臨時文件 須要自行刪除
		file = File.createTempFile("pattern", "." + suffix);
		tempFilePath = file.getCanonicalPath();
		System.out.println("臨時文件位置:" + tempFilePath);
		FileOutputStream fstream = new FileOutputStream(file);
		stream = new BufferedOutputStream(fstream);
		stream.write(byteFile);
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		if (stream != null) {
			try {
				stream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	return file;
}

/**
 * @Function: 根據地址得到數據的字節流 - GET請求
 * @param url - 網絡鏈接地址
 */
private static byte[] getImageFromNetByUrl(String strUrl) {
	try {
		URL url = new URL(strUrl);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setRequestMethod("GET");
		conn.setConnectTimeout(5 * 1000);
		// 經過輸入流獲取圖片數據
		InputStream inStream = conn.getInputStream();
		// 獲得圖片的二進制數據
		byte[] btImg = readInputStream(inStream);
		return btImg;
	} catch (Exception e) {
		e.printStackTrace();
	}
	return null;
}

/**
 * @Function: 從輸入流中獲取數據
 * @param inStream - 輸入流
 * @throws IOException
 */
private static byte[] readInputStream(InputStream inStream) throws IOException {
	ByteArrayOutputStream outStream = new ByteArrayOutputStream();
	byte[] buffer = new byte[1024];
	int len = 0;
	while ((len = inStream.read(buffer)) != -1) {
		outStream.write(buffer, 0, len);
	}
	inStream.close();
	return outStream.toByteArray();
}

/**
 * @Function: 刪除臨時文件
 */
public static Boolean deleteFile() {
	boolean flag = false;
	File file = new File(tempFilePath);
	// 路徑爲文件且不爲空則進行刪除
	if (file.isFile() && file.exists()) {
		file.delete();
		flag = true;
	}
	return flag;
}

/**
 * @Function: base64編碼圖片轉 MultipartFile
 * 注意 轉碼時 須要把data:image/png;base64,這個前綴給去掉
 */
public static MultipartFile base64ToMultipart(String base64) {
	if (base64.indexOf(",") > -1) {
		String[] baseStrs = base64.split(",");
		if (null != baseStrs && baseStrs.length > 0) {
			byte[] b = new byte[0];
			b = Base64.decodeFast(baseStrs[1]);
			for (int i = 0; i < b.length; ++i) {
				// 調整異常數據
				if (b[i] < 0) {
					b[i] += 256;
				}
			}
			return new BASE64DecodedMultipartFile(b, baseStrs[0]);
		}
	}
	return null;
}

/**
 * @Function: 將一張網絡圖片轉化成Base64字符串
 * @param imgSrc - 網絡圖片資源位置 
 */
public static String getImageBase64StrFromUrl(String imgSrc){
	URL url = null;  
    InputStream is = null;   
    ByteArrayOutputStream outStream = null;  
    HttpURLConnection httpUrl = null; 
    
    try{  
        url = new URL(imgSrc);  
        httpUrl = (HttpURLConnection) url.openConnection();  
        httpUrl.setRequestMethod("GET");
        httpUrl.setConnectTimeout(5 * 1000);
        httpUrl.connect();  
        httpUrl.getInputStream();  
        is = httpUrl.getInputStream();            
          
        outStream = new ByteArrayOutputStream();  
        //建立一個Buffer字符串  
        byte[] buffer = new byte[1024];  
        //每次讀取的字符串長度,若是爲-1,表明所有讀取完畢  
        int len = 0;  
        //使用一個輸入流從buffer裏把數據讀取出來  
        while( (len=is.read(buffer)) != -1 ){  
            //用輸出流往buffer裏寫入數據,中間參數表明從哪一個位置開始讀,len表明讀取的長度  
            outStream.write(buffer, 0, len);  
        }  
        // 對字節數組Base64編碼  
        return java.util.Base64.getEncoder().encodeToString(outStream.toByteArray());
    }catch (Exception e) {  
        e.printStackTrace();  
    }finally{  
        if(is != null) {  
            try {is.close(); } catch (IOException e) {e.printStackTrace(); }  
        }  
        if(outStream != null) {  
            try {outStream.close();} catch (IOException e) {e.printStackTrace();}  
        }  
        if(httpUrl != null){ httpUrl.disconnect();}  
    }  
    return imgSrc; 
}
複製代碼

}跨域

二、自定義 BASE64DecodedMultipartFile 類數組

package com.aaa.bbb.ccc.ddd.helper;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.springframework.web.multipart.MultipartFile;

/**
 * @Function : 自定義 BASE64DecodedMultipartFile 類
 * @Author & @Date : lynn_ - 2018年06月15日
 */
public class BASE64DecodedMultipartFile implements MultipartFile {

	private final byte[] imgContent;
	private final String header;

	public BASE64DecodedMultipartFile(byte[] imgContent, String header) {
		this.imgContent = imgContent;
		this.header = header.split(";")[0];
	}

	@Override
	public String getName() {
		return System.currentTimeMillis() + "." + header.split("/")[1];
	}

	@Override
	public String getOriginalFilename() {
		return System.currentTimeMillis() + "." + header.split("/")[1];
	}

	@Override
	public String getContentType() {
		return header.split(":")[1];
	}

	@Override
	public boolean isEmpty() {
		return imgContent == null || imgContent.length == 0;
	}

	@Override
	public long getSize() {
		return imgContent.length;
	}

	@Override
	public byte[] getBytes() throws IOException {
		return imgContent;
	}

	@Override
	public InputStream getInputStream() throws IOException {
		return new ByteArrayInputStream(imgContent);
	}

	@SuppressWarnings("resource")
	@Override
	public void transferTo(File dest) throws IOException, IllegalStateException {
		new FileOutputStream(dest).write(imgContent);
	}
}
複製代碼

三、下面開始 調用測試安全

//根據圖片SRC獲取圖片Base64編碼
String base64Str = WebFileUtils.getImageBase64StrFromUrl(imgSrc);
System.out.println(base64Str);

//圖片base64編碼轉 MultipartFile
MultipartFile mf = WebFileUtils.base64ToMultipart(src_base64Str);

//IMG的SRC地址轉爲File; File轉換成MutipartFile
File file = WebFileUtils.createFileByUrl(imgsrc, "png");
FileInputStream inputStream = new FileInputStream(file);
MultipartFile multipartFile = new MockMultipartFile(imgName, imgOriginalFileName, contentType, inputStream);
複製代碼

---------------------------------- END ---------------------------------服務器

相關文章
相關標籤/搜索