我正在使用 java 从扫描仪设备捕获图像。输入格式是 PGM 或 TIFF。我必须在用户界面中显示实时结果。实际上,我使用ImageJ将源输入流读取为 tiff,因为 ImageJ 还可以处理不完整的流。之后,ImagePlus
对象被转换为 aBufferedImage
并最终转换为 JavaFX Image
。
ImagePlus imagePlus = new Opener().openTiff(inputStream, "");
BufferedImage bufferedImage = imagePlus.getBufferedImage();
Image image = SwingFXUtils.toFXImage(bufferedImage, null);
这是非常缓慢的。我需要一种更快的方法来Image
从 PGM 或 TIFF 流创建 JavaFX。似乎 JavaFX 实际上不支持这种格式,我也没有找到有用的库。
任何想法?
编辑#1
我决定分两步优化图像捕获。首先,在更新 ui 中的图像时,我需要更好的状态控制。这实际上已经完成并且工作正常。现在,当转换线程忙时,更新请求被丢弃。第二步是使用自行实现的 pnm 阅读器(基于建议的实现)并逐步更新我的模型中的图像......直到扫描过程完成。从设备加载图像时,这应该会减少所需的资源。我需要改变我的架构的某些部分来实现这一点。
谢谢@大家的意见。
顺便说一句:java 8 lambda 很棒:)
编辑#2
我的计划行不通,因为 JavaFX 的线程测试 :(
目前我的WritableImage
后端有一个应该逐步填充数据。此图像实例设置ObjectProperty
为最终绑定到ImageView
. 由于WritableImage
连接到 ,ImageView
因此无法使用PixelWriter
. 这会导致异常。
java.lang.IllegalStateException: Not on FX application thread; currentThread = pool-2-thread-1
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:210) ~[jfxrt.jar:na]
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:393) ~[jfxrt.jar:na]
at javafx.scene.Scene.addToDirtyList(Scene.java:529) ~[jfxrt.jar:na]
at javafx.scene.Node.addToSceneDirtyList(Node.java:417) ~[jfxrt.jar:na]
at javafx.scene.Node.impl_markDirty(Node.java:408) ~[jfxrt.jar:na]
at javafx.scene.Node.transformedBoundsChanged(Node.java:3789) ~[jfxrt.jar:na]
at javafx.scene.Node.impl_geomChanged(Node.java:3753) ~[jfxrt.jar:na]
at javafx.scene.image.ImageView.access$700(ImageView.java:141) ~[jfxrt.jar:na]
at javafx.scene.image.ImageView$3.invalidated(ImageView.java:285) ~[jfxrt.jar:na]
at javafx.beans.WeakInvalidationListener.invalidated(WeakInvalidationListener.java:83) ~[jfxrt.jar:na]
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:135) ~[jfxrt.jar:na]
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80) ~[jfxrt.jar:na]
at javafx.beans.property.ReadOnlyObjectPropertyBase.fireValueChangedEvent(ReadOnlyObjectPropertyBase.java:74) ~[jfxrt.jar:na]
at javafx.scene.image.Image$ObjectPropertyImpl.fireValueChangedEvent(Image.java:568) ~[jfxrt.jar:na]
at javafx.scene.image.Image.pixelsDirty(Image.java:542) ~[jfxrt.jar:na]
at javafx.scene.image.WritableImage$2.setArgb(WritableImage.java:170) ~[jfxrt.jar:na]
at javafx.scene.image.WritableImage$2.setColor(WritableImage.java:179) ~[jfxrt.jar:na]
我的解决方法是创建图像的副本,但我不喜欢这种解决方案。也许可以阻止自动更改通知并手动执行此操作?