首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Java中使用JAI进行TIFF渲染时性能更快

在Java中使用JAI进行TIFF渲染时性能更快
EN

Stack Overflow用户
提问于 2011-12-06 12:45:28
回答 4查看 2.2K关注 0票数 3

我一直在开发分析显微镜数据的软件,这些数据被存储为多层tiff文件。在阅读了StackOverflow和JAI文档之后,我拼凑了一些代码来存储tiff堆栈并正确地呈现它。

然而,它的性能却很差。在阅读了这样的帖子后,我曾希望能有更快的性能:Anyone have any luck writing a very fast tiff viewer/editor in Java?

不幸的是,它远没有我希望的那么好。我在使用外部图像库或Java的Graphics功能方面没有太多经验,所以我不确定如何改进这一点。

下面是我在遍历tiff堆栈时遇到的“卡顿”的视频:http://www.youtube.com/watch?v=WiR4o6TsqyM&feature=channel_video_title

请注意,当拖动滑块时,帧偶尔会卡顿。

我通过删除缩放时的平滑来提高图像放大时的性能,但它仍然不像我希望的那样快。

我的代码如下:

代码语言:javascript
复制
/** 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();
}

我已经使用JAI将多层tiff加载到imageDecoder中,为了在拖动滑块时显示正确的层,我使用以下代码:

代码语言:javascript
复制
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一起使用),缩放它,并将其设置为显示的图像。我认为最慢的部分是将其转换为缓冲图像,并对其进行缩放。有没有更快的方法呢?

有没有人有任何关于如何改进事情的建议,或者从类似的经验中获得的见解?

任何帮助都将不胜感激。

EN

回答 4

Stack Overflow用户

发布于 2013-03-20 03:11:24

我遇到了完全相同的问题,最终使用decodeAsRaster()传递给convert方法:

代码语言:javascript
复制
public static BufferedImage convertRenderedImage(Raster raster) {
    int w = raster.getWidth();
    int h = raster.getHeight();
    BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    int[] sourcePixels = ((DataBufferInt)raster.getDataBuffer()).getData();
    int[] destPixels = ((DataBufferInt)image.getRaster().getDataBuffer()).getData();
    System.arraycopy(pixels, 0, rasterData, 0, pixels.length); // The speed-up!
    return image;
}

然后将您的代码更改为:

代码语言:javascript
复制
currImage = convertRenderedImage(imageStack.decodeAsRaster(currentLayerSlider.getValue()-1));

速度提高的功劳要归功于@Brent Nash here:我们基本上从原始的栅格和像素数组中获得像素数组,供BufferedImage填充并执行System.arraycopy,而不是“昂贵的”image.setData(raster),后者更便携,但对于每个像素,调用一些方法来检查一致性和类型,而我们已经有了所需的所有信息。

这段代码应该对BufferedImage.TYPE_INT_RGB有效,尽管我必须承认我无法测试它,但我知道它在BufferedImage.TYPE_BYTE_GRAY (和byte[]/DataBufferByte)上是有效的。

票数 3
EN

Stack Overflow用户

发布于 2012-03-14 20:43:58

除了在JLabel中使用BufferedImage和ImageIcon之外,您是否尝试过使用DisplayJAI?它可以直接显示RenderedImage。

票数 0
EN

Stack Overflow用户

发布于 2014-02-04 13:46:31

您可以将渲染图像更改为缓冲区,然后将其显示在j标签中,因为渲染图像是jai图像,而j标签采用唯一的缓冲区图像,并且不尝试在jai中显示它。您可以在jLabel中尝试它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8395456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档