Java 中图片 base64 编码的相互转换

哈喽大家好我是你爸啊。

今天项目优化了一下上传头像的功能。

如果图片以文件的形式在前后端传输不是很方便

于是将图片转成  base64 加密的字符串,在前后端传输,自然上传头像也就涉及到了如何把加密的字符串转换成图片的问题。

首先呢在网上找到很多,都是使用的  sun.misc.Base64Encoder和sun.misc.Base64Decoder这个在 Java高版本用不了而且有缺陷

因此楼主采用的替代方案是使用  commons-codec是Apache下面的一个加解密开发包

pom 

<!-- Base64编码转换 -->
        <dependency>
            <groupId>servlets.com</groupId>
            <artifactId>cos</artifactId>
            <version>05Nov2002</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.10</version>
        </dependency>

下面呢是一个工具类,等下我们上传图片到服务器的时候会用到

package com.dheaven.utils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

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

public class BaseCodeToPicUtils {

    /**
     * @Description: 将base64编码字符串转换为图片
     * @Author: 
     * @CreateTime: 
     * @param imgStr base64编码字符串
     * @param path 图片路径-具体到文件
     * @return
     * @throws FileNotFoundException 
    */
    public static void generateImage(String imgStr, String path) throws Exception {
        OutputStream out = null;
        Base64 base64 = new Base64();
        byte[] b = base64.decodeBase64(imgStr);
        for (int i = 0; i < b.length; i++) {
                if(b[i]<0) {
                    b[i]+=256;
                }
        }
        out = new FileOutputStream(path);
        out.write(b);
        out.flush();
        out.close();
    }
    /**
     * @Description: 根据图片地址转换为base64编码字符串
     * @Author: 
     * @CreateTime: 
     * @return
     */
    public static String getImageStr(String imgFile) {
        InputStream inputStream = null;
        byte[] data = null;
        try {
            inputStream = new FileInputStream(imgFile);
            data = new byte[inputStream.available()];
            inputStream.read(data);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 加密
        Base64 base64 = new Base64();
        return base64.encodeToString(data);
    }
        
    /**
     * 示例
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        String strImg = getImageStr("C:\\Users\\Administrator\\Desktop\\Test\\126.jpg");
        System.out.println("111111"+strImg);
        generateImage(strImg, "C:\\Users\\Administrator\\Desktop\\Test\\132.png");
    }

}


上面就是准备工作啦,都Ok啦,接下来我们写 comtroller

/**
	 * 用户上传头像
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception 
	 */
	@ResponseBody
	@RequestMapping(value="/uploadPic", method = { RequestMethod.POST, RequestMethod.GET})
	public ResponseData uploadPic(HttpServletRequest request,HttpServletResponse response,@RequestBody UploadPicRequest uploadPicRequest) throws Exception{
		response.setHeader("Access-Control-Allow-Origin", "*");
		Map<String, Object> map = new HashMap<String, Object>();
		ResponseData resp = null;
		String userName = uploadPicRequest.getUserName();
		String imgStr = uploadPicRequest.getUploadPicStr();
		if(StringUtils.isEmpty(userName)) {
			resp = new ResponseData(ResponseEnum.ERROR, "userName为空");
		}
		if(StringUtils.isEmpty(imgStr)||imgStr.length()<7) {
			resp = new ResponseData(ResponseEnum.ERROR, "图片编码有误");
		}
		String ID = userService.getIdByUserName(userName);
		//这里是要截取前端传递过来的图片编码,图片加密的字符串前缀包含   data:image/jpeg;base64, 
		//我们要把这个处理去掉才能调用我们封装的工具类转成图片,不然图片会无法展示
		int indexOf = imgStr.indexOf("base64,");
		//处理过后的在用原来的字符串接受
		imgStr=imgStr.substring(indexOf+7);
		try {
			if (null != imgStr) {
				uploadPic(request, map, imgStr, ID);
			} else {
				resp = new ResponseData(ResponseEnum.ERROR, "上传头像为空");
			}
		} catch (Exception e) {
			resp = new ResponseData(ResponseEnum.ERROR, "上传头像失败");
		}
		return resp;
	}


	private void uploadPic(HttpServletRequest request, Map<String, Object> map, String imgStr, String ID)
			throws Exception {
		ResponseData resp;
		//项目服务器地址路径
		String projectServerPath = request.getScheme() + "://" + request.getServerName() + ":"+ request.getServerPort() + "/uploadPic/imgs/headPortrait/";
		logger.info("项目服务器地址路径 :"+projectServerPath);
		//上传文件路径
		String path = request.getSession().getServletContext().getRealPath("/").substring(0,request.getSession().getServletContext().getRealPath("/").indexOf(request.getContextPath().substring(1)))+"uploadPic/imgs/headPortrait/";
		logger.info("上传文件路径 :"+path);
		//新文件名称
		String originalFilename = System.currentTimeMillis() + ".jpg";
		//判断路径是否存在,如果不存在就创建一个
		File file = new File(path+originalFilename);
		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}
		//将64位编码转换成图片并且上传到服务器下
		BaseCodeToPicUtils.generateImage(imgStr, path + originalFilename);
		String serverFilePatn = projectServerPath + originalFilename;
		logger.info("访问 服务器图片地址 : "+serverFilePatn);
		map.put("id", ID);
		map.put("headPortrait", serverFilePatn);
		// 更新用户头像信息
		userService.uploadPic(map);
		resp = new ResponseData(ResponseEnum.SUCCESS, "上传头像成功  : ");
		resp.setJson(serverFilePatn);
	}

到上面我们的功能就做完啦

里面有service我是调用自己的

你要复制的可能会报错改成自己的即可

首先是要和前端约定好将图片转成加密字符串传输给后台

其次我们拿到字符串后通过解密将字符串转换成图片

之后将图片写入服务器的  webapp 下

将访问服务器上图片的地址保存到用户表

同时返回给前端展示

这里上传到 webapp/WEB-INF 下会有一个问题

当你重启 tomcat 之前上传的头像都会消失呢

网上解决方案很多,我的这个是 在 webapp 下创建啦同级的目录

我的在代码中 上传文件路径下的那一行代码后面添加了   /uploadPic/imgs/headPortrait/

这个是需要注意下的

猜你喜欢

转载自blog.csdn.net/Architect_CSDN/article/details/90209921
今日推荐