【问题标题】:Convert base64 string to image将base64字符串转换为图像
【发布时间】:2014-07-21 16:53:22
【问题描述】:

我正在尝试使用 jquery 插件裁剪/调整用户个人资料图像的大小,即crop.js,它通过 ajax 将用户图像作为 base64 发送到我的控制器作为

$.ajax({
         type: "post",
         dataType: "json",
         url: "${g.createLink(controller: 'personalDetail', action:'uploadUserImage')}",
         data: { avatar: canvas.toDataURL() }

        });

但我无法解码这个 base64

'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAYAAAA+VemSAAAgAEl...==' 

string as Image,你们能指导我如何将我的base64字符串作为图像保存在我的服务器上吗?

【问题讨论】:

  • 您可以在编码字符串iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAYAAAA+VemSAAAgAEl 上直接使用decodeBase64() 来获取字节数组,然后按照答案创建文件。

标签: java ajax image grails base64


【解决方案1】:

在服务器中,执行如下操作:

假设

String data = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAYAAAA+VemSAAAgAEl...=='

然后:

String base64Image = data.split(",")[1];
byte[] imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(base64Image);

然后你可以对字节做任何你喜欢的事情,比如:

BufferedImage img = ImageIO.read(new ByteArrayInputStream(imageBytes));

【讨论】:

  • 这个“javax.xml.bind.DatatypeConverter.parseBase64Binary”比使用字符串中的“.getBytes()”方法更好
【解决方案2】:

这假设了一些事情,即您知道输出文件名是什么,并且您的数据以字符串的形式出现。我相信您可以修改以下内容以满足您的需求:

// Needed Imports
import java.io.ByteArrayInputStream;
import sun.misc.BASE64Decoder;


def sourceData = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAYAAAA+VemSAAAgAEl...==';

// tokenize the data
def parts = sourceData.tokenize(",");
def imageString = parts[1];

// create a buffered image
BufferedImage image = null;
byte[] imageByte;

BASE64Decoder decoder = new BASE64Decoder();
imageByte = decoder.decodeBuffer(imageString);
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();

// write the image to a file
File outputfile = new File("image.png");
ImageIO.write(image, "png", outputfile);

请注意,这只是所涉及部分的一个示例。我根本没有优化这段代码,它已经写在我的脑海里了。

【讨论】:

  • @Lucky Groovy 不需要在行尾使用分号。
  • 如果您打算使用 JDK > 8,那么此代码将无法工作,因为在 JDK 8 中无法访问 Base64Decoder。我更喜欢使用 javax.xml.bind.DatatypeConverter 而不是 Base64Decoder 或来自 sun 的任何类.*** 包。
  • ImageIO.write()默认会压缩图像,压缩后的图像尺寸较小,但有时看起来很奇怪。我使用BufferedOutputStream保存字节数组数据,这样可以保持原始图像大小。
  • @Ayano 我该怎么做?
  • @styl3r 我已经在这个问题下面写了完整的代码。 my answer
【解决方案3】:

ImageIO.write() 默认会压缩图像 - 压缩后的图像尺寸较小但有时看起来很奇怪。我使用BufferedOutputStream 保存字节数组数据 - 这将保持原始图像大小。

代码如下:

import javax.xml.bind.DatatypeConverter;
import java.io.*;

public class ImageTest {
    public static void main(String[] args) {
        String base64String = "data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAHkAAAB5C...";
        String[] strings = base64String.split(",");
        String extension;
        switch (strings[0]) {//check image's extension
            case "data:image/jpeg;base64":
                extension = "jpeg";
                break;
            case "data:image/png;base64":
                extension = "png";
                break;
            default://should write cases for more images types
                extension = "jpg";
                break;
        }
        //convert base64 string to binary data
        byte[] data = DatatypeConverter.parseBase64Binary(strings[1]);
        String path = "C:\\Users\\Ene\\Desktop\\test_image." + extension;
        File file = new File(path);
        try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file))) {
            outputStream.write(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

【讨论】:

    【解决方案4】:

    简单是:

    import java.util.Base64;
    

    解码:

    byte[] image = Base64.getDecoder().decode(base64string);
    

    编码:

    String text = Base64.getEncoder().encodeToString(imageData);
    

    【讨论】:

      【解决方案5】:

      服务器端将文件/图像编码为 base64String 以供客户端使用

      public Optional<String> InputStreamToBase64(Optional<InputStream> inputStream) throws IOException{
          if (inputStream.isPresent()) {
              ByteArrayOutputStream output = new ByteArrayOutputStream();
              FileCopyUtils.copy(inputStream.get(), output);
              //TODO retrieve content type from file, & replace png below with it
              return Optional.ofNullable("data:image/png;base64," + DatatypeConverter.printBase64Binary(output.toByteArray()));
          }
      
          return Optional.empty();
      }
      

      服务器端 base64 图像/文件解码器

      public Optional<InputStream> Base64InputStream(Optional<String> base64String)throws IOException {
          if (base64String.isPresent()) {
              return Optional.ofNullable(new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(base64String.get())));
          }
      
          return Optional.empty();
      }
      

      【讨论】:

        【解决方案6】:
          public Optional<String> InputStreamToBase64(Optional<InputStream> inputStream) throws IOException{
            if (inputStream.isPresent()) {
                ByteArrayOutputStream outpString base64Image = data.split(",")[1];
        byte[] imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(base64Image);
        

        然后你可以对字节做任何你喜欢的事情,比如:

        BufferedImage img = ImageIO.read(new ByteArrayInputStream(imageBytes));ut = new ByteArrayOutputStream();
                FileCopyUtils.copy(inputStream.get(), output);
                //TODO retrieve content type from file, & replace png below with it
                return Optional.ofNullable("data:image/png;base64," + DatatypeConverter.printBase64Binary(output.toByteArray()));
            }
        
            return Optional.empty();
        

        【讨论】:

          【解决方案7】:

          嗨,这是我的解决方案

          Javascript代码

          var base64before = document.querySelector('img').src;
          var base64 = base64before.replace(/^data:image\/(png|jpg);base64,/, "");
          var httpPost = new XMLHttpRequest();
          var path = "your url";
          var data = JSON.stringify(base64);
          
          httpPost.open("POST", path, false);
          // Set the content type of the request to json since that's what's being sent
          httpPost.setRequestHeader('Content-Type', 'application/json');
          httpPost.send(data);
          

          这是我的 Java 代码。

          public void saveImage(InputStream imageStream){
          InputStream inStream = imageStream;
          
          try {
              String dataString = convertStreamToString(inStream);
          
              byte[] imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(dataString);
              BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
              // write the image to a file
              File outputfile = new File("/Users/paul/Desktop/testkey/myImage.png");
              ImageIO.write(image, "png", outputfile);
          
              }catch(Exception e) {
                  System.out.println(e.getStackTrace());
              }
          }
          
          
          static String convertStreamToString(java.io.InputStream is) {
              java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
              return s.hasNext() ? s.next() : "";
          }
          

          【讨论】:

            【解决方案8】:

            这是 Ayano 的出色答案,但在 Clojure 中:

            (:import (java.awt.image BufferedImage)
                     (javax.xml.bind DatatypeConverter)
                     (java.io File BufferedOutputStream FileOutputStream))
            
            (defn write-svg-encountered-image [svg-img-data base-filename]
              (let [[meta img-data] (str/split svg-img-data #",")
                    extension (case meta
                                "data:image/jpeg;base64" ".jpeg"
                                "data:image/png;base64" ".png"
                                (throw (Error. (format "Unrecognised image metadata in SVG:" meta))))
                    path (str base-filename extension)
                    file (File. path)
                    data-bytes (DatatypeConverter/parseBase64Binary img-data)
                    os (BufferedOutputStream. (FileOutputStream. file))]
                  (.write os data-bytes)))
            

            【讨论】:

              猜你喜欢
              • 2018-09-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-09-14
              • 2011-06-17
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多