我正在尝试将屏幕截图输出作为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写入磁盘上的文件。
答案 0 :(得分:15)
以下陈述的工作方向错误:
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");
答案 1 :(得分: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);
}
}
在屏幕截图中使用它:
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");
答案 2 :(得分:9)
我跟着xehpuk's回答,但是在某些浏览器中通过数据网址(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);
}
}
这解决了在浏览器中渲染时缺少像素行的问题。
答案 3 :(得分:0)
这对我有用:
将图像编码为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;
}
答案 4 :(得分:0)
实际上,两种不同解决方案的组合对我有用。我的用例是从 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);
我通过将结果转换为实际图像来确认结果。效果惊人。