Преобразовать строку 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
@ Аяно, как мне это сделать? - 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