Convert base64 string to image
Asked Answered
F

9

66

I am trying to crop/resize user profile image using jquery plugin namely crop.js which sends user image as base64 via ajax to my controller as

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

        });

but I unable to decode this base64

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

string as Image,Can you guys guide me how can I save my base64 string as image on my server?.

Fortdefrance answered 1/6, 2014 at 12:25 Comment(1)
You can use decodeBase64() on the encoded string iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAYAAAA+VemSAAAgAEl directly to get the byte array and then create the file as shown in answers.Talkington
M
77

This assumes a few things, that you know what the output file name will be and that your data comes as a string. I'm sure you can modify the following to meet your needs:

// 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);

Please note, this is just an example of what parts are involved. I haven't optimized this code at all and it's written off the top of my head.

Moolah answered 1/6, 2014 at 12:39 Comment(6)
@Lucky Groovy doesn't require semicolons at the end of lines.Moolah
If you are planning to use JDK > 8 then this code will not work as Base64Decoder is not accessible in JDK 8. I prefer to use javax.xml.bind.DatatypeConverter over Base64Decoder or any class from sun.*** package.Elboa
The ImageIO.write() would compress the image by default,the compressed image has the smaller size,but looks strange sometimes. I used the BufferedOutputStream to save the byte array data,this would keep the original image size.Fatherless
@Fatherless how do I do that?Lightish
@styl3r I had write the full code of that below this question. my answerFatherless
ImageIO should be avoided for saving.Samothrace
C
99

In the server, do something like this:

Suppose

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

Then:

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

Then you can do whatever you like with the bytes like:

BufferedImage img = ImageIO.read(new ByteArrayInputStream(imageBytes));
Coeternal answered 1/6, 2014 at 12:43 Comment(1)
This "javax.xml.bind.DatatypeConverter.parseBase64Binary" better than use ".getBytes()" method from a StringBaseline
M
77

This assumes a few things, that you know what the output file name will be and that your data comes as a string. I'm sure you can modify the following to meet your needs:

// 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);

Please note, this is just an example of what parts are involved. I haven't optimized this code at all and it's written off the top of my head.

Moolah answered 1/6, 2014 at 12:39 Comment(6)
@Lucky Groovy doesn't require semicolons at the end of lines.Moolah
If you are planning to use JDK > 8 then this code will not work as Base64Decoder is not accessible in JDK 8. I prefer to use javax.xml.bind.DatatypeConverter over Base64Decoder or any class from sun.*** package.Elboa
The ImageIO.write() would compress the image by default,the compressed image has the smaller size,but looks strange sometimes. I used the BufferedOutputStream to save the byte array data,this would keep the original image size.Fatherless
@Fatherless how do I do that?Lightish
@styl3r I had write the full code of that below this question. my answerFatherless
ImageIO should be avoided for saving.Samothrace
F
31

ImageIO.write() will compress the image by default - the compressed image has a smaller size but looks strange sometimes. I use BufferedOutputStream to save the byte array data - this will keep the original image size.

Here is the code:

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();
        }
    }
}
Fatherless answered 17/7, 2018 at 3:34 Comment(0)
F
9

Simplicity is:

import java.util.Base64;

To decode:

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

To encode:

String text = Base64.getEncoder().encodeToString(imageData);
Fingerstall answered 6/3, 2020 at 10:37 Comment(1)
for this, min OS is Android O.Sarver
D
5

Server side encoding files/Images to base64String ready for client side consumption

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();
}

Server side base64 Image/File decoder

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

    return Optional.empty();
}
Devisee answered 24/1, 2015 at 5:6 Comment(0)
E
4
  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);

Then you can do whatever you like with the bytes like:

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();
Eldenelder answered 6/4, 2017 at 9:52 Comment(0)
C
2

Hi This is my solution

Javascript code

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);

This is my Java code.

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() : "";
}
Crichton answered 4/6, 2018 at 14:16 Comment(0)
S
0

This is Ayano's excellent answer, but in 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)))
Scourge answered 10/3, 2022 at 8:15 Comment(0)
G
-1

To Convert all file types

 String[] strings = expense.getAttchBase64().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;
                    case "data:application/pdf;base64":
                        extension = "pdf";
                        break;
                    case "data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64":
                        extension = "docx";
                        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 fileName = UUID.randomUUID().toString();
                String path = "C:\\floridatrading\\" + fileName + "." + extension;
                File file = new File(path);
                try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file))) {
                    outputStream.write(data);
                } catch (IOException e) {
                    e.printStackTrace();
                }

if you need to add any new type just add It in switch .

Gristmill answered 9/9, 2022 at 13:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.