2011-12-06 2 views
3

나는 다층 tiff 파일로 저장되어있는 현미경 데이터를 분석하는 소프트웨어를 연구하고 있습니다. StackOverflow와 JAI 문서를 살펴본 후, Tiff 스택을 저장하고 올바르게 렌더링 할 수있는 몇 가지 코드를 모았습니다.Java에서 JAI를 사용하여 TIFF 렌더링의 성능 향상

그러나 꽤 나쁜 성능이 있습니다. 다음과 같은 게시물을 읽은 후 좀 더 빠른 실적을 기대했습니다. Anyone have any luck writing a very fast tiff viewer/editor in Java?

불행히도, 내가 기대했던 것만 큼 좋지는 않습니다. 필자는 외부 이미지 라이브러리 나 자바의 그래픽 기능에 대한 경험이별로 없기 때문에 어떻게 향상 시킬지 확신 할 수 없습니다. 슬라이더를 드래그로 프레임이 때때로 더듬 방법 http://www.youtube.com/watch?v=WiR4o6TsqyM&feature=channel_video_title

참고 : 일부 컨텍스트에 대한

, 여기에 티파니 스택을 통해 통과하는 동안 경험하는 '망가'의 동영상입니다.

스케일링시 이미지가 확대되어 퍼포먼스가 제거 될 때 퍼포먼스가 향상되었지만 여전히 빨랐습니다.

내 코드는 다음과 같습니다 : 나는 JAI과 imageDecoder에 다층 티파니를로드 한, 슬라이더를 드래그 할 때, 나는 다음과 같은 코드를 사용 올바른 계층을 표시

/** 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(); 
} 

:

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과 함께 사용할 수 있도록) 크기를 조정 한 다음 표시된 이미지로 설정합니다. 나는 느린 부분이 그것을 버퍼 된 이미지로 변환하고 그것을 스케일링한다고 생각한다. 이 작업을 더 빨리 수행 할 수있는 방법이 있습니까?

누군가를 향상시키는 방법이나 비슷한 경험에 대한 통찰력이있는 사람이 있습니까?

도움을 주시면 감사하겠습니다.

답변

0

JLabel 용 BufferedImage 및 ImageIcon 대신 DisplayJAI를 사용해 보셨습니까? RenderedImage를 직접 표시 할 수 있습니다.

3

나는 똑같은 문제로 실행하고 변환 방법에 전달할 decodeAsRaster()를 사용 만난다 :

currImage = convertRenderedImage(imageStack.decodeAsRaster(currentLayerSlider.getValue()-1)); 

속도 향상의 신용 :

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; 
} 

그런 다음에 코드를 변경 @Brent Nash here : 기본적으로 원래 래스터의 픽셀 배열과 BufferedImage 픽셀 배열을 채우고 "비싼"대신 System.arraycopy을 수행합니다. 0은 더 이식성이 뛰어나지 만, 각 픽셀에 대해 일관성과 유형을 확인하는 몇 가지 메소드를 호출합니다. 우리는 이미 필요한 모든 정보를 가지고 있습니다.

나는 그것을 테스트 할 수 없습니다 고백해야하지만이 코드는 BufferedImage.TYPE_INT_RGB 유효해야하지만, 나는 그것이 BufferedImage.TYPE_BYTE_GRAY (및 byte[]/DataBufferByte)에서 일하고있어 알고있다.

0

당신은 당신이 JLabel의

에서 그것을 시도 버퍼 다음 renderd 이미지 재이 이미지와 J 라벨이 onley 버퍼 이미지를 촬영하고 재이에 표시하려고하지 않기 때문에 J 라벨에 표시하기에 renderd 이미지를 변경할 수 있습니다