Я работал над программным обеспечением, которое анализирует данные микроскопии, которые хранятся в виде многослойного файла формата TIFF. Просмотрев StackOverflow и документацию JAI, я собрал некоторый код для хранения стека TIFF и правильного его рендеринга.
Тем не менее, он страдает от довольно плохой производительности. Я надеялся на более быструю производительность после прочтения постов, таких как эта:
Кому-нибудь посчастливилось написать очень быстрый просмотрщик / редактор tiff на Java?
К сожалению, это не так хорошо, как я бы надеялся. У меня нет большого опыта работы с внешними библиотеками изображений или с графическими возможностями 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 в imageDecoder с JAI, и для отображения правильного слоя при перетаскивании ползунка я использую следующий код:
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), масштабирую его и устанавливаю в качестве отображаемого изображения. Я думаю, что медленная часть преобразует его в буферизованное изображение и масштабирует его. Есть ли способ сделать это быстрее?
Есть ли у кого-нибудь какие-либо предложения о том, как улучшить положение вещей или понять, как это происходит?
Любая помощь будет высоко ценится.