Java BufferedImage в формат PNG Base64 String - PullRequest
15 голосов
/ 24 августа 2011

Я пытаюсь получить вывод на скриншот в виде строки в кодировке base64, но не очень далеко. Код, который у меня есть, использует библиотеку Base64 (http://iharder.sourceforge.net/current/java/base64/):

    Robot robot = new Robot();
    Rectangle r = new Rectangle( Toolkit.getDefaultToolkit().getScreenSize() );
    BufferedImage bi = robot.createScreenCapture(r);
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    OutputStream b64 = new Base64.OutputStream(os);
    ImageIO.write(bi, "png", os);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    out.writeTo(b64);
    String result = out.toString("UTF-8");

Каждый раз, когда я запускаю это, «результат» всегда пустая строка, но я не понимаю почему. Есть идеи?

Примечание: я не хочу записывать png в файл на диске.

Ответы [ 4 ]

15 голосов
/ 24 августа 2011

Следующий оператор работает в неправильном направлении:

out.writeTo(b64);

Он перезаписывает данные Base 64 пустым байтовым массивом out.

Какова цель outтем не мение?Я не думаю, что вам это нужно.

Обновление:

И вы записываете изображение непосредственно в os вместо записи через кодировщик Base 64.

Следующий код должен работать:

...
ByteArrayOutputStream os = new ByteArrayOutputStream();
OutputStream b64 = new Base64.OutputStream(os);
ImageIO.write(bi, "png", b64);
String result = os.toString("UTF-8");
11 голосов
/ 04 августа 2014

Кодирование Base64 и декодирование изображений с использованием Java 8:

public static String imgToBase64String(final RenderedImage img, final String formatName) {
    final ByteArrayOutputStream os = new ByteArrayOutputStream();
    try {
        ImageIO.write(img, formatName, Base64.getEncoder().wrap(os));
        return os.toString(StandardCharsets.ISO_8859_1.name());
    } catch (final IOException ioe) {
        throw new UncheckedIOException(ioe);
    }
}

public static BufferedImage base64StringToImg(final String base64String) {
    try {
        return ImageIO.read(new ByteArrayInputStream(Base64.getDecoder().decode(base64String)));
    } catch (final IOException ioe) {
        throw new UncheckedIOException(ioe);
    }
}

Используйте это так для сценария скриншота:

final Robot robot = new Robot();
final Rectangle r = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
final BufferedImage bi = robot.createScreenCapture(r);
final String base64String = imgToBase64String(bi, "png");
9 голосов
/ 09 марта 2017

Я следовал за ответом xehpuk, но у него были проблемы с определенными изображениями, в которых отсутствовали последние несколько строк пикселей при визуализации в определенных браузерах через URL-адрес данных (Chrome и Firefox, Safari, похоже, отображал их нормально). Я подозреваю, что это потому, что браузер делает все возможное, чтобы интерпретировать данные, но последние несколько байтов данных отсутствовали, поэтому он показывает, что он может.

Кажется, причиной этой проблемы является обтекание выходного потока. Документация для Base64.wrap(OutputStream os) объясняет:

Рекомендуется незамедлительно закрыть возвращенный выходной поток после использования, во время которого он сбрасывает все возможные оставшиеся байты в базовый выходной поток.

Таким образом, в зависимости от длины данных, возможно, что последние несколько байтов не сбрасываются из потока, потому что close() не вызывается для него. Мое решение этого состояло в том, чтобы не беспокоить обтекание потока и просто закодировать поток непосредственно:

public static String imgToBase64String(final RenderedImage img, final String formatName)
{
  final ByteArrayOutputStream os = new ByteArrayOutputStream();

  try
  {
    ImageIO.write(img, formatName, os);
    return Base64.getEncoder().encodeToString(os.toByteArray());
  }
  catch (final IOException ioe)
  {
    throw new UncheckedIOException(ioe);
  }
}

Это решило проблемы с отсутствующими рядами пикселей при визуализации в браузере.

0 голосов
/ 18 июля 2018

Это работает для меня:

Кодирование изображения в строку Base64

public static String encodeToString(BufferedImage image, String type) {
    String imageString = null;
    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    try {
        ImageIO.write(image, type, bos);
        byte[] imageBytes = bos.toByteArray();

        Base64.Encoder encoder = Base64.getEncoder();
        imageString = encoder.encodeToString(imageBytes);

        bos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return imageString;
}

Декодирование строки Base64 в изображение

public static BufferedImage decodeToImage(String imageString) {
    BufferedImage image = null;
    byte[] imageByte;
    try {
        Base64.Decoder decoder = Base64.getDecoder();
        imageByte = decoder.decode(imageString);
        ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
        image = ImageIO.read(bis);
        bis.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return image;
}
...