Javaを使用してスキャナーデバイスから画像をキャプチャしています。入力形式は PGM または TIFF です。ユーザー インターフェイスにライブ結果を表示する必要があります。ImageJ は不完全なストリームも処理できるため、実際にはImageJを使用してソース入力ストリームを tiff として読み取ります。その後、ImagePlus
オブジェクトは に変換され、BufferedImage
最終的に JavaFX に変換されますImage
。
ImagePlus imagePlus = new Opener().openTiff(inputStream, "");
BufferedImage bufferedImage = imagePlus.getBufferedImage();
Image image = SwingFXUtils.toFXImage(bufferedImage, null);
これは非常に遅いです。Image
PGM または TIFF ストリームからJavaFX を作成するより高速な方法が必要です。JavaFX は実際にはこの形式をサポートしていないようで、便利なライブラリが見つかりません。
何か案が?
編集#1
画像のキャプチャを 2 つのステップで最適化することにしました。最初に、UI で画像を更新するときに、状態をより適切に制御する必要があります。これは実際に行われ、正常に動作します。変換スレッドがビジーの場合、更新リクエストがドロップされるようになりました。2 番目のステップは、(提案された実装に基づいて) 自己実装された pnm リーダーを使用し、スキャン プロセスが完了するまでモデルのイメージを段階的に更新することです。これにより、デバイスからイメージをロードするときに必要なリソースが削減されます。これを実現するには、アーキテクチャの一部を変更する必要があります。
@ コメントありがとうございます。
ところで:Java 8ラムダは素晴らしいです:)
編集#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]
私の回避策はイメージのコピーを作成することですが、この解決策は好きではありません。自動変更通知を防ぎ、これを手動で行うことは可能でしょうか?