2013-11-21 13 views
4

이미지의 작은 부분 만 화면에 표시 할 수있는 매우 큰 이미지 (디스크의 png에서)를 표시해야하는 애플리케이션이 있습니다. 그러나 보이는 부분은 큰 이미지를 중심으로 빠르게 움직일 수 있습니다.큰 이미지를 Java로 빠르게로드하십시오.

전체 이미지를 BufferedImage에 한 번에로드하는 것은 좋지 않습니다. 크기는 10 000 - 100 000 픽셀 일 수 있지만 디스크의 크기는 그리 크지 않습니다 (아마도 몇 MB 정도). 그래서 질문입니다. 표시 할 관련 섹션 만로드합니다.

FileImageInputStream is = new FileImageInputStream(imageFile); 
ImageReader imageReader = ImageIO.getImageReaders(is).next(); 
ImageReader.setInput(is, false, true); 
ImageReadParam readParameters = imageReader.getDefaultReadParam(); 

그리고 다음과 같은 서브 이미지 무언가를 얻기위한 방법 :

는이 같은 ImageReader를 만드는 시도했습니다 이것은 원칙적으로 작동

private BufferedImage loadFrame(int x, int y, int w, int h) { 
    readParameters.setSourceRegion(new Rectangle(x,y,w,h)); 
    try { 
     return imageReader.read(0, readParameters); 
    } catch (IOException ex) { 
     return null; 
    } 
} 

을하지만 너무하다 느린. 그래서 이미지 주위를 빠르게 움직일 때 그것은 너무 많이 뒤쳐집니다.

또한 소스 이미지를 미리 분할하여 디스크에 작은 이미지가 많이 있으므로 ImageIO.read(getImageFile(x,y))을 사용하여 필요한만큼로드했습니다. 여기서 getImageFile(x,y)은 해당 위치에 대해 File을 반환합니다. 이 방법은 사실 훨씬 빠르고 완벽하게 사용할 수있었습니다.

이 작업을 수행 할 방법이 있다고 생각하지만이 방법을 사용하는 것은 다소 어색한 것으로 보입니다. 원본 이미지의 일부 준비가 필요함과 동시에 많은 디스크 액세스가 필요합니다 (아마 어딘가에 버퍼링되어있을 것입니다).

내 질문은 : 이것을 수행하는 가장 좋은 방법은 무엇입니까? (왜 ImageReader에서 이미지의 일부를로드하는 것보다 디스크에서 이미지를로드하는 것이 더 빠릅니까?)

답변

2

PNG는 압축 된 형식이므로 파일을 열어 특정 위치를 찾을 수 없습니다. 영역을 읽기 시작하십시오 (물론 파일 헤더를 읽은 후에 비트 맵 ~로 할 수있는 것처럼). 영역을 추출하기 전에 전체 PNG를로드 (구문 분석/압축 해제)해야합니다. (http://en.wikipedia.org/wiki/Portable_Network_Graphics#File_header)

당신은

  • 당신은 이미지를 분할하고를 구축해야 만 그리드 청크를로드 할 수 있습니다 ... 향상된 메모리 (RAM) 사용 및 성능에 디스크 공간을 희생하려는 경우 사용자보기
    • 1x1.png, 1x2.png, 2x1.png는 2x2.png - 사용자가 왼쪽 상단에보고되는 경우에만 1x1.png 등 등
  • 당신을로드해야합니다 이미지를 비트 맵 BMP로 변환 할 수 있습니다. 이미지는 디스크에서 훨씬 더 커지지 만 전체 파일을 처리하지 않고도 특정 영역을 추출 할 수 있습니다.
+0

확인. 아마도 PNG의 일부분 만 압축을 풀 수 있다고 생각 했겠지만 생각해 보면 압축 형식을 설계하는 것이 쉽지 않거나 효과적이지 않을 것이라고 생각합니다. (물론 PNG는 그런 형식이 아닙니다. 체재). 귀하의 답변 주셔서 감사합니다! – zephyr

관련 문제