Как преобразовать список <String>строк в BufferedImage в Java - PullRequest
2 голосов
/ 10 апреля 2019

Я хочу преобразовать массив Base64 String в BufferedImage. Подход, который я пытался реализовать:

static BufferedImage decodeToImage(List<String> imageStrings) {
    BufferedImage image = null;
    ByteBuffer imageByteBuffer = ByteBuffer.allocate(500000000);
    try {
        BASE64Decoder decoder = new BASE64Decoder();
        for (String imageString : imageStrings) {
            imageByteBuffer.put(imageString.getBytes());
        }

        ByteArrayInputStream bis = new ByteArrayInputStream(imageByteBuffer.array());
        image = ImageIO.read(bis);
        bis.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return image;
}

Я хочу вернуть BufferedImage, но он возвращает ноль.

Ответы [ 4 ]

2 голосов
/ 10 апреля 2019

Вы можете просто использовать это:

public static BufferedImage decodeToImage(List<String> imageStrings) {
    try {
        byte[] bytes = Base64.getDecoder().decode(String.join("", imageStrings));
        return ImageIO.read(new ByteArrayInputStream(bytes));
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
}
1 голос
/ 12 апреля 2019

Действительно ли максимальная длина строки в Java является проблемой для вашего кода?Если нет, я бы упростил ваш код следующим образом (и исправил бы ошибку декодирования):

static BufferedImage decodeToImage(String imageString) {
    try {
        BASE64Decoder decoder = new BASE64Decoder();    
        return ImageIO.read(new ByteArrayInputStream(decoder.decode(imageString)));
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}

Или, если у вас действительно есть проблема с длиной строк (Base64 выводит больше, чемввод, так что может иметь смысл в крайних случаях, но проверьте это, так как в противном случае ваш код станет ненужным), сохраняйте список строк.Я бы просто пропустил ByteBuffer и использовал бы вместо него ByteArrayOutputStream, так как с ним гораздо проще работать.

static BufferedImage decodeToImage(List<String> imageStrings) {
    try {
        ByteArrayOuputStream buffer = new ByteArrayOuputStream();

        BASE64Decoder decoder = new BASE64Decoder();
        for (String imageString : imageStrings) {
            buffer.write(decoder.decode(imageString));
        }

        return ImageIO.read(new ByteArrayInputStream(buffer.toArray()));
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}

PS: Хотя вы обычно должны закрывать потоки, метод close() для ByteArrayInputStream и ByteArrayOutputStream бездействуют.

1 голос
/ 10 апреля 2019

Вы смотрели на то, что вы получаете?

Причините этот код

public static void main(String[] args) {
    String base64String = "data:image/png;base64,iVBORw0...=";
    String[] strings = base64String.split(",");
    List<String> param = new ArrayList<String>();
    param.add(strings[1]);
    BufferedImage bi = decodeToImage(param);
    System.out.println("BufferedImage: " + bi);
}

static BufferedImage decodeToImage(List<String> imageStrings) {
    BufferedImage image = null;
    ByteBuffer imageByteBuffer = ByteBuffer.allocate(500000000);
    try {
        for (String imageString : imageStrings) {
          imageByteBuffer.put(DatatypeConverter.parseBase64Binary(imageString));
        }
        ByteArrayInputStream bis = new ByteArrayInputStream(imageByteBuffer.array());
        image = ImageIO.read(bis);
        bis.close();
    } catch (Exception e) {
        System.out.println("error?");
        e.printStackTrace();
    }
    return image;
}

Распечатает

BufferedImage: BufferedImage @ 7eda2dbb: type = 6 ColorModel: #pixelBits = 32 numComponents = 4 цветового пространства = java.awt.color.ICC_ColorSpace@6576fe71 232 #numDataElements 4 dataOff [0] = 3

Но если я просто дам ему весь текст base64 с информацией об изображении впереди

 public static void main(String[] args) {
    String base64String = "data:image/png;base64,iVBORw0...=";
    String[] strings = base64String.split(",");
    List<String> param = new ArrayList<String>();
    param.add(base64String); //THIS IS THE DIFFERENT LINE
    BufferedImage bi = decodeToImage(param);
    System.out.println("BufferedImage: " + bi);
    }

Будет напечатано ноль

Заменить base64String на действительный png с кодировкой base 64 из

http://freeonlinetools24.com/base64-image

Я сократил его в этом примере, иначе он станет длиной в несколько тысяч символов.

0 голосов
/ 10 апреля 2019

С буферами немного сложно работать. Может быть, хорошая идея, чтобы посмотреть здесь: https://docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html#flip()

Насколько я помню, вам нужно подготовить буфер, прежде чем вы сможете его прочитать; Положение внутреннего «курсора» должно быть установлено в начальную позицию, откуда вы затем можете прочитать «объемные» байты. Ну, как я уже сказал: насколько я помню. Больше двенадцати лет назад мне приходилось работать с буферами напрямую.

...