Java BufferedImage到PNG格式的Base64字符串

use*_*003 16 java base64 png bufferedimage

我试图将屏幕截图输出作为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");
Run Code Online (Sandbox Code Playgroud)

每次我运行它,"结果"总是一个空字符串,但我不明白为什么.有任何想法吗?

注意:我不想将png写入磁盘上的文件.

Cod*_*odo 15

以下声明的工作方向错误:

out.writeTo(b64);
Run Code Online (Sandbox Code Playgroud)

它用空字节数组覆盖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");
Run Code Online (Sandbox Code Playgroud)


xeh*_*puk 11

使用Java 8对图像进行Base64编码和解码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

对于截图方案,请使用以下方法:

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");
Run Code Online (Sandbox Code Playgroud)


Rob*_*unt 10

我遵循了xehpuk的回答,但是在某些浏览器中通过数据网址(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);
  }
}
Run Code Online (Sandbox Code Playgroud)

这解决了在浏览器中呈现时缺少像素行的问题.