javafx调整图像大小的内存消耗提示

标签 java image memory-management bufferedimage graphics2d

我有一个简单的javafx应用程序,它可以批量操作图像(只是调整大小:))这是一个简单的javafx表单,带有源目录textField、目标目录textField和所需的尺寸。启动此应用程序后,没有任何操作的简单形式会消耗大约 65MB 内存...开始批处理后,内存消耗跳至 250 MB,然后不断增加。在处理 700 张图像后,我的应用程序消耗了大约 1,35GB 内存(图片大小约为 3500x2600 像素,大小已调整为 1920x1080)。如果我在每个图像后调用 gc(),则内存约为 300 - 350 MB。但是您是否对 javafx 应用程序的较小内存要求有一些提示,或者 350 MB 就可以了,因为 Java 是虚拟机。感谢您的提示。大约几年前,我用 C# 编写了类似的应用程序,它消耗了大约 60 MB 的内存:) 它有很大的不同 :( 但我喜欢 Java 和多平台应用程序。当然,我通过 在第二个线程中打开图像ImageIO.read(),然后转换为 BufferedImage(),然后我用较小的尺寸创建新的 BufferedImage() 并绘制原始的 BufferedImage() 通过 Graphics2D() 生成新的较小图像

BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, type);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g.dispose();

最后

ImageIO.write(backgroundThread.resize(1920, 1080), "jpg", new File(destinationPath +      f.getFileName()));

感谢帮助

最佳答案

使用JavaFX Image constructor创建图像并调整其大小,而不是使用 BufferedImageImageIO

内存消耗应改善为:

  1. 发生的格式转换较少,因此不需要存储中间格式。
  2. 当使用 JavaFX Image 构造函数时,JavaFX javadoc 指定:

    Images can be resized as they are loaded (for example to reduce the amount of memory consumed by the image)

<小时/>

其他问题的答案

how I can save it on disk?

使用 JavaFX 将图像保存到磁盘目前(从最初的 Java 8 版本开始)是一个开放的、 Unresolved 功能请求:RT-18886 Implement Image writers for JavaFX

在实现 RT-18886 之前,您需要将图像转换为 BufferedImage在保存之前,为了使用 ImageIO用于将图像保存为 jpg 等格式。您可以使用SwingFXUtils去做这个。当您第一次将图像加载到内存中时,预先调整图像大小仍然是有效的,这就是 JavaFX Image 构造函数的工作原理。

I must also create a new Buffered Image and then draw it inside with Graphics2D.

您可以将图像加载为 JavaFX 图像,然后将其绘制在 JavaFX Canvas 上,使用 JavaFX GraphicsContext ,然后 snapshot the canvas获取一个新图像,您可以将其转换为 BufferedImage 并使用 ImageIO 保存。好吧,也许这不是最有效的流程,但它确实允许您(主要)坚持使用单个框架和 API,并避免一些潜在的线程问题。

I using SwingFXUtils.fromFXImage(im, null) but I have a strange filter on the pictures then

我不知道“奇怪的过滤器”到底是什么意思,但也许您正在看到RT-14647 Incorrect display of JPEG images ,该问题已在过去的 JavaFX 更新中修复。尝试针对最新的 Java 8 development release 运行看看您是否仍然遇到同样的问题。如果没有,您可以使用 mcve 创建一个新问题.

<小时/>

替代方案

几乎可以肯定,有一种等效的方法可以仅使用 BufferedImage、ImageIO 和 awt/swing 框架来有效地保存调整大小的图像,但我对该 API 不够熟悉,无法评论如何完成此操作,而且我不是粉丝混合 Swing、AWT 和 JavaFX,除非您确实需要。

关于javafx调整图像大小的内存消耗提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25401185/

相关文章:

java - 如何测量通过 netbeans 中的 tomcat 运行的 Java Web 应用程序中的 CPU 和内存

java - Spring框架在测试应用方面有哪些优势?

java - 记录对象哈希码有用吗?

Java Swing 使用 Socket 进行企业应用

javascript - 带灯箱的图片库 - 图像链接未正确与其他链接交换

ios - 为什么我应该避免在整个应用程序中只使用一个 UIViewController

java - 在 pom.xml 中生成 Maven 依赖项的简单方法?

image - 如何在 Xamarin.Forms 中使用 XAML 从嵌入式资源设置图像

c - 如何用手电筒添加图像 channel ?

c - 如何在函数调用过程中释放堆栈内存