2018-06-15: Java 将网络图片SRC转换为Base64, Base64转 MultipartFile

---------------------------------- BEGIN ---------------------------------

背景: 项目需要,不同服务器之间图片截图互传,JS new Image() 涉及到跨域问题,于安全考虑,禁用服务器跨域,于是周转了如下解决方案。

具体逻辑:
java 后台 根据图片SRC获取图片Base64编码供前台显示, 前台 JS 操作(裁剪、截图,前面文章有具体方法 JS 自定义 截图、裁剪), 完成后将Base64字符串传到后台,后台解码生成MultipartFile ...

1、先上 公共的文件处理类 WebFileUtils

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; 
}
复制代码

}

2、自定义 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);
	}
}
复制代码

3、下面开始 调用测试

//根据图片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 ---------------------------------

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值