我正在使用Robot的screenCapture方法返回BufferedImage,然后使用Socket发送到Android上的客户端。如果我不降低质量,那么它工作正常,但它非常慢,因为图像很大,需要很长时间才能发送。 我正在尝试降低BufferedImage的质量(使用ImageResizer类),但它的工作时间非常有限,然后在服务器端崩溃....它给了我以下异常
Exception in thread "Thread-7" Exception in thread "Thread-8" java.lang.OutOfMemoryError: Java heap space
at sun.awt.windows.WRobotPeer.getRGBPixels(WRobotPeer.java:64)
at java.awt.Robot.createScreenCapture(Robot.java:444)
at SystemController.screenCap(SystemController.java:71)
at Server$ImageServer.run(Server.java:356)
at java.lang.Thread.run(Thread.java:722)**
我正在使用以下课程来调整大小
public class ImageResizer {
public static ByteArrayOutputStream resizeImage(BufferedImage image) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
float quality = 0.3f; // Change this as needed
// get all image writers for JPG format
Iterator<ImageWriter> writers = ImageIO
.getImageWritersByFormatName("jpg");
if (!writers.hasNext()) {
throw new IllegalStateException("No writers found");
}
ImageWriter writer = writers.next();
//ImageOutputStream ios = ImageIO.createImageOutputStream(os);
try (ImageOutputStream ios = ImageIO.createImageOutputStream(out)) {
writer.setOutput(ios);
// set compression quality
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
writer.write(null, new IIOImage(image, null, null), param);
}
} catch (IOException ex) {
ex.printStackTrace();
}
return out;
}
}
此方法用于捕获
public ByteArrayOutputStream screenCap(Rectangle captureSize, int i) {
robot = new Robot();
screenImage = robot.createScreenCapture(captureSize);
return ImageResizer.resizeImage(screenImage);
}
我做错了什么?
答案 0 :(得分:0)
OutOfMemory错误在使用BufferedImage时并不罕见,因为BufferedImage与内存中的未压缩图像一起使用,因此JPEG编码的图像在光盘上可能需要300kb,这可能占用10mb内存,具体取决于方式你可以处理图像大小调整过程,这可以占用更多(通过创建很多BufferedImages)。
我的建议是使用像imgscalr这样的图像缩放库,过去我曾经使用imgscalr来改善使用BufferedImages疯狂调整图像的传统Java应用程序的内存使用情况
使用imgscalr可以很简单:
BufferedImage thumbnail = Scalr.resize(image, 150);