繁体   English   中英

Java BufferedImage转PNG格式Base64字符串

[英]Java BufferedImage to PNG format Base64 String

我正在尝试将屏幕截图输出作为 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 写入磁盘上的文件。

我遵循了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);
  }
}

这解决了在浏览器中呈现时丢失像素行的问题。

以下语句的工作方向错误:

out.writeTo(b64);

它用out的空字节数组覆盖 Base 64 数据。

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

使用 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);
    }
}

像这样在你的截图场景中使用它:

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

这对我有用:

将图像编码为 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;
}

实际上,两种不同解决方案的组合对我有用。 我的用例是从 zip 文件中读取图像。 这是对我有用的代码:

BufferedImage bgTileSprite = ImageIO.read(inputStream);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(bgTileSprite, "png", os);
String result = Base64.getEncoder().encodeToString(os.toByteArray());
LOGGER.info(result);

我通过将结果转换为实际图像来确认结果。 它的作用很神奇。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM