Java - 将base64编码解码成图片

为了方便测试,我们可以使用一个,将图片进行base64编码

解密的代码如下

public static String generateImage(String base64, String path) {
    // 解密
    try {
      String savePath = "/**/imgtest/";
      // 图片分类路径+图片名+图片后缀
      String imgClassPath = path.concat(UUID.randomUUID().toString()).concat(".jpg");
​
      // 去掉base64前缀 data:image/jpeg;base64,
      base64 = base64.substring(base64.indexOf(",", 1) + 1);
      // 解密,解密的结果是一个byte数组
      Base64.Decoder decoder = Base64.getDecoder();
      byte[] imgbytes = decoder.decode(base64);
      for (int i = 0; i < imgbytes.length; ++i) {
        if (imgbytes[i] < 0) {
          imgbytes[i] += 256;
        }
      }
      
      // 保存图片
      OutputStream out = new FileOutputStream(savePath.concat(imgClassPath));
      out.write(imgbytes);
      out.flush();
      out.close();
      // 返回图片的相对路径 = 图片分类路径+图片名+图片后缀
      return imgClassPath;
    } catch (IOException e) {
      return null;
    }
}

因为图片的Base64字符串非常大,动辄几百K,所以不能直接使用String base64 = "${该图片的base64串}"进行测试,否则编译器会报错Java "constant string too long" compile error"。这个错误的出现,是因为字符串常量值的长度超过了65534,编译期检查没通过。运行时不存在这个限制,运行时的内存限制走的是堆内存,跟CPU分配内存相关。

解决方法1:如果将字符串预先存到一个文件里,使用的时候再从文件里读出来,就不会有什么问题

// 从文件中读取字符串
public static String getFileContent(FileInputStream fis, String encoding) throws IOException {
  try (BufferedReader br = new BufferedReader(new InputStreamReader(fis, encoding))) {
    StringBuilder sb = new StringBuilder();
    String line;
    while ((line = br.readLine()) != null) {
      sb.append(line);
    }
    return sb.toString();
  }
}
​
​
public static void main(String[] args) throws IOException {
  // 从txt文件中读取base64字符串
  FileInputStream fis = new FileInputStream("/Users/valor/workspace/imgtest/bigimg.txt");
  String base64 = getFileContent(fis, "UTF-8");
​
  String path = "";
​
  // 将base64字符串翻译成图片
  String fileName = generateImage(base64, path);
  System.out.println(fileName);
}

解决方法2:或者如果我们是处于前后端数据交换的环境中,由于json对于string的长度是没有限制的,所以可以直接使用@ResponseBody通过一个Bean,去接收这串base64。

// bean
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ImgInfo {
    Long id;
    String base64;
}
​
// controller
@RestController
public class String2ImgController {
​
    @Autowired
    private String2ImgService imgService;
​
    @PostMapping("/img/base64")
    public String transferImg(@RequestBody ImgInfo imgInfo) {
​
        String base64 = imgInfo.getBase64();
        // System.out.println(base64);
      
        // 去掉base64前缀 data:image/jpeg;base64,
        base64 = base64.substring(base64.indexOf(",", 1) + 1);
        // 解密,解密的结果是一个byte数组
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] imgbytes = decoder.decode(base64);
        for (int i = 0; i < imgbytes.length; ++i) {
          if (imgbytes[i] < 0) {
            imgbytes[i] += 256;
          }
        }
      
      // 对 byte 数组进行你所需要的操作……
    }
}
经验分享 程序员 微信小程序 职场和发展