私は、多層 tiff ファイルとして保存されている顕微鏡データを分析するソフトウェアに取り組んできました。StackOverflow と JAI ドキュメントに目を通した後、TIFF スタックを格納して正しくレンダリングするためのコードをまとめました。
ただし、かなり悪いパフォーマンスに悩まされています。次のような投稿を読んだ後、パフォーマンスの高速化を期待していました 。
残念ながら、私が望んでいたほど良くはありません。私は外部の画像ライブラリや Java のグラフィックス機能を使った経験があまりないので、これをどのように改善できるかわかりません。
状況によっては、TIFF スタックをトラバースしているときに発生する「吃音」のビデオを次に示します: http://www.youtube.com/watch?v=WiR4o6TsqyM&feature=channel_video_title
スライダーをドラッグすると、フレームがときどきカクカクすることに注意してください。
スケーリング時のスムージングを削除することで、画像をズームインしたときのパフォーマンスを改善しましたが、それでも思ったほど速くはありません。
私のコードは以下の通りです:
/** Converts the RenderedImage into a BufferedImage, which is more flexible
* @param img The original RenderedImage
* @return The new BufferedImage
*/
public BufferedImage convertRenderedImage(RenderedImage img) {
if (img instanceof BufferedImage) {
return (BufferedImage)img;
}
ColorModel cm = img.getColorModel();
int width = img.getWidth();
int height = img.getHeight();
WritableRaster raster = cm.createCompatibleWritableRaster(width, height);
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
Hashtable<String, Object> properties = new Hashtable<String, Object>();
String[] keys = img.getPropertyNames();
if (keys!=null) {
for (int i = 0; i < keys.length; i++) {
properties.put(keys[i], img.getProperty(keys[i]));
}
}
BufferedImage result = new BufferedImage(cm, raster, isAlphaPremultiplied, properties);
img.copyData(raster);
return result;
}
/** Draws everything on top of the scaled image
* @param scale The current scale value
*/
private void setScaledImage(double scale)
{
//Optimizes the image type for drawing onto the screen
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = env.getDefaultScreenDevice();
GraphicsConfiguration config = device.getDefaultConfiguration();
int w = (int)(scale*currImage.getWidth());
int h = (int)(scale*currImage.getHeight());
scaled = config.createCompatibleImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = scaled.createGraphics();
g2.drawImage(currImage, 0, 0, w, h, null);
g2.dispose();
}
マルチレイヤー tiff を JAI を使用して imageDecoder にロードし、スライダーをドラッグしたときに正しいレイヤーを表示するために、次のコードを使用します。
try {
currImage = convertRenderedImage(imageStack.decodeAsRenderedImage(currentLayerSlider.getValue()-1));
setScaledImage (scaleSlider.getValue()/100.0);
curves.changeFrame(currentLayerSlider.getValue());
drawImageOverlay ();}
catch (IOException e) {
e.printStackTrace();
currImage = null;}
基本的に、スライダーがドラッグされるたびに、imageStack からレンダリングされたイメージを抽出し、それを BufferedImage に変換して (ImageIcon で使用できるように)、スケーリングして、表示イメージとして設定します。遅い部分は、バッファリングされた画像に変換してスケーリングしていると思います。これをより速く行う方法はありますか?
物事を改善する方法についての提案や、同様の経験からの洞察はありますか?
どんな助けでも大歓迎です。