Преобразувайте base64 низ в изображение

Опитвам се да изрежа/преоразмеря изображение на потребителския профил с помощта на jquery плъгин, а именно crop.js, който изпраща потребителско изображение като base64 чрез ajax към моя контролер като

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

        });

но не мога да декодирам този base64

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

низ като изображение, можете ли да ме напътствате как мога да запазя своя base64 низ като изображение на моя сървър?.


person Abs    schedule 01.06.2014    source източник
comment
Можете да използвате decodeBase64() върху кодирания низ iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAYAAAA+VemSAAAgAEl директно, за да получите масива от байтове и след това да създадете файла, както е показано в отговорите.   -  person dmahapatro    schedule 01.06.2014


Отговори (7)


Това предполага няколко неща, че знаете какво ще бъде името на изходния файл и че вашите данни идват като низ. Сигурен съм, че можете да промените следното, за да отговаря на вашите нужди:

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

Моля, имайте предвид, че това е само пример за това какви части са включени. Изобщо не съм оптимизирал този код и е отписан от главата ми.

person Joshua Moore    schedule 01.06.2014
comment
@Lucky Groovy не изисква точка и запетая в края на редовете. - person Joshua Moore; 30.05.2015
comment
Ако планирате да използвате JDK › 8, тогава този код няма да работи, тъй като Base64Decoder не е достъпен в JDK 8. Предпочитам да използвам javax.xml.bind.DatatypeConverter над Base64Decoder или който и да е клас от sun.*** пакет. - person Sudhir Dhumal; 01.05.2016
comment
ImageIO.write() ще компресира изображението по подразбиране, компресираното изображение има по-малък размер, но понякога изглежда странно. Използвах BufferedOutputStream, за да запазя данните от байтовия масив, това ще запази оригиналния размер на изображението. - person Ayano; 10.08.2017
comment
@Ayano как да направя това? - person styl3r; 13.07.2018
comment
@styl3r Бях написал пълния код на това под този въпрос. моят отговор - person Ayano; 17.07.2018
comment
ImageIO трябва да се избягва за запазване. - person clankill3r; 27.09.2019

В сървъра направете нещо подобно:

Да предположим

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));
person user711189    schedule 01.06.2014
comment
Този javax.xml.bind.DatatypeConverter.parseBase64Binary е по-добър от използването на метод .getBytes() от String - person Kyo Huu; 06.05.2019

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();
        }
    }
}
person Ayano    schedule 17.07.2018

За декодиране:

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

За кодиране:

String text = Base64.getEncoder().encodeToString(imageData);
person Please_Dont_Bully_Me_SO_Lords    schedule 06.03.2020

Кодиращи файлове/изображения от страна на сървъра към 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();
}
person iamiddy    schedule 24.01.2015

  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();
person mero    schedule 06.04.2017

Здравейте, това е моето решение

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() : "";
}
person paulrda    schedule 04.06.2018