2009-07-01 4 views
35

자바에서 JPEG의 미리보기 이미지를 만드는 데 도움이되는 코드가 있습니까?Java에서 JPEG로 축소판 이미지를 어떻게 만듭니 까?

저는이 부분에 익숙하지 않으므로 단계별 설명이 도움이 될 것입니다.

+3

http://www.google.com/search?hl=ko&q=java+thumbnail+jpg –

+1

ImageMagick과 같은 라이브러리 사용 - 웹에 많은 예제가 있습니다. – mfloryan

+0

죄송합니다. 오타를 고쳐 주셔서 감사합니다. 나는 prolly 편집 후 더 많은 오타를 소개해서는 안됩니다 ... – jjnguy

답변

59
Image img = ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, BufferedImage.SCALE_SMOOTH); 

이렇게하면 이미지 개체로 100x100 픽셀 미리보기 이미지가 생성됩니다. 다시 디스크에 기록 할 경우 단순히이에 코드를 변환 :

BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); 
img.createGraphics().drawImage(ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, Image.SCALE_SMOOTH),0,0,null); 
ImageIO.write(img, "jpg", new File("test_thumb.jpg")); 

당신이 속도 문제에 대한 우려 또한 경우 (위에서 설명한 방법은 다소 느리다는 많은 이미지를 확장 할 경우) 이러한 방법을 사용 다음 선언 : 다음

private BufferedImage scale(BufferedImage source,double ratio) { 
    int w = (int) (source.getWidth() * ratio); 
    int h = (int) (source.getHeight() * ratio); 
    BufferedImage bi = getCompatibleImage(w, h); 
    Graphics2D g2d = bi.createGraphics(); 
    double xScale = (double) w/source.getWidth(); 
    double yScale = (double) h/source.getHeight(); 
    AffineTransform at = AffineTransform.getScaleInstance(xScale,yScale); 
    g2d.drawRenderedImage(source, at); 
    g2d.dispose(); 
    return bi; 
} 

private BufferedImage getCompatibleImage(int w, int h) { 
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    GraphicsDevice gd = ge.getDefaultScreenDevice(); 
    GraphicsConfiguration gc = gd.getDefaultConfiguration(); 
    BufferedImage image = gc.createCompatibleImage(w, h); 
    return image; 
} 

및 호출 0.5 스케일 비율 및 IMG는 보통 크기의 이미지가 포함되는 BufferedImage이다

BufferedImage scaled = scale(img,0.5); 

한다.

+0

덕분에 도움. 정확하고 정확합니다. – Ayusman

+0

이 코드는 java.nio 패키지로 변경됩니까? (디스크에 다시 쓰는 것) – jacktrades

+1

@ 잭 트레이드는 그렇지 않습니다. 'ImageIO.write()'메서드를 사용하여 디스크에 다시 기록 할 수 있습니다. 나는 그 주석이 매우 오래되었지만 잭과 같은 질문을하는 사람들에게 그렇습니다. – kevto

4

JMagick 라이브러리 (및 Java에서 ImageMagick의 구현)에 필요한 것이 있습니다.

+0

+1 그리고 많은 출력 결과를 얻을 수 있습니다. –

+1

이것은 ImageMagick 주변의 단순한 기본 인터페이스입니다. 문제 1 : 외부 의존성 문제 2 : Java에서 네이티브 함수 호출. 이것은 JMagick을 차선책으로 만든다. – gyorgyabraham

3

위의 자바 코드 (scale/getCompatibleImage 메소드 사용)는 훌륭하게 작동했지만 서버에 배포 할 때 서버에 연결된 디스플레이가 없어서 작동이 중지되었습니다. 다음을 사용하여 수정하십시오. BufferedImage bi = new BufferedImage (w, h, BufferedImage.TYPE_INT_RGB);

대신 BufferedImage bi = getCompatibleImage (w, h);

과 getCompatibleImage 방법을

(나중에 메모를 삭제 - 이것이 가장 이미지 좋은 작품 밝혀,하지만 난 32 비트 색 깊이 JPEG 이미지입니다 내 회사의 마케팅 부서의 무리를 가지고, 라이브러리 (imagemagick/jmagick이 더 매력적으로 보이기 시작했습니다.)

30

"쉬운"과 "좋은 결과"를 알 수있는 것은 두 가지 매우 다른 것들입니다. 이 두 가지 요구 사항을 매우 간단하게 java image scaling library (Apache 2 라이센스)으로 캡슐화하여 모든 것을 올바르게 처리 할 수 ​​있습니다.

썸네일을 만들

예제 코드는 다음과 같습니다

BufferedImage img = ImageIO.read(...); // load image 
BufferedImage scaledImg = Scalr.resize(img, 150); 
귀하의 이미지 비율이 영광

, 라이브러리가 그것이 이미지의 변화량으로 인한 기반으로 사용해야하는 방법에 가장 생각합니다 스케일링 (FASTEST, BALANCED 또는 QUALITY) 및 지원되는 최상의 Java2D 이미지 유형은 항상 "검은 색"결과 또는 정말로 끔찍한 출력물 (예. 지나치게 디더 된 GIF 이미지).당신이 출력 자바에서 가능한 최고의 찾고 썸네일을 강제하려는 경우

또한, API 호출은 다음과 같이 보일 것이다 :

BufferedImage img = ImageIO.read(...); // load image 
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY, 
             150, 100, Scalr.OP_ANTIALIAS); 

뿐만 아니라 라이브러리가 사용하는 Java2D에 당신을 위해 증분 스케일링을 권장 최상의 결과를 얻으려면 축소판에 선택적 안티 앨리어싱 효과 (매우 미세 조정 된 커널의 ConvolveOp)를 적용하여 픽셀 값 사이의 전환을 부드럽게 처리하여 축소판을보다 균일하게 보이게 만듭니다. 날카로운 양귀비는 매우 큰 이미지에서 아주 작은 이미지로 이동할 때 보았을 것입니다.

성능이 나 메모리 사용을 개선하기 위해 수행 된 최적화 또는 다른 모든 JDK 버그를 보려면 라이브러리의 모든 주석 (코드 자체가 많이 사용됨)을 읽을 수 있습니다. 이 구현을 튜닝하는 데 많은 시간을 할애하여 웹 애플리케이션 및 기타 Java 프로젝트에 배포하는 사람들로부터 좋은 피드백을 많이 받았습니다.

+0

이것은 정말 멋져 보인다, 정말 고마워! –

+0

고마워요.이 lib는 정말 굉장합니다. 위에서 언급 한 방법 중 아무 것도 내 테스트 이미지에서 작동하지 않았지만 당신은 매력처럼 작동했습니다. 나는 당신이 준 다양한 크기 조정 옵션을 좋아합니다. –

+0

@cracked_all 친절한 단어를 보내 주셔서 감사합니다. 나는 당신의 인생을 더 쉽게 만들어 준 것을 기쁘게 생각합니다! –

12

이것은 이미지에 스트레치 또는 비뚤어 짐없이 100x100 크기의 축소판을 만드는 간단한 방법입니다.

private void saveScaledImage(String filePath,String outputFile){ 
    try { 

     BufferedImage sourceImage = ImageIO.read(new File(filePath)); 
     int width = sourceImage.getWidth(); 
     int height = sourceImage.getHeight(); 

     if(width>height){ 
      float extraSize= height-100; 
      float percentHight = (extraSize/height)*100; 
      float percentWidth = width - ((width/100)*percentHight); 
      BufferedImage img = new BufferedImage((int)percentWidth, 100, BufferedImage.TYPE_INT_RGB); 
      Image scaledImage = sourceImage.getScaledInstance((int)percentWidth, 100, Image.SCALE_SMOOTH); 
      img.createGraphics().drawImage(scaledImage, 0, 0, null); 
      BufferedImage img2 = new BufferedImage(100, 100 ,BufferedImage.TYPE_INT_RGB); 
      img2 = img.getSubimage((int)((percentWidth-100)/2), 0, 100, 100); 

      ImageIO.write(img2, "jpg", new File(outputFile));  
     }else{ 
      float extraSize= width-100; 
      float percentWidth = (extraSize/width)*100; 
      float percentHight = height - ((height/100)*percentWidth); 
      BufferedImage img = new BufferedImage(100, (int)percentHight, BufferedImage.TYPE_INT_RGB); 
      Image scaledImage = sourceImage.getScaledInstance(100,(int)percentHight, Image.SCALE_SMOOTH); 
      img.createGraphics().drawImage(scaledImage, 0, 0, null); 
      BufferedImage img2 = new BufferedImage(100, 100 ,BufferedImage.TYPE_INT_RGB); 
      img2 = img.getSubimage(0, (int)((percentHight-100)/2), 100, 100); 

      ImageIO.write(img2, "jpg", new File(outputFile)); 
     } 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

} 
+0

많은 형제에게 고마워 ..... 내 문제가 해결되었습니다. 다시 고마워 :-) – Farhan

+0

정말 잘 작동합니다. – webcoder

+0

BufferedImage img2 = 새 BufferedImage (100, 100, BufferedImage.TYPE_INT_RGB); img2 = img.getSubimage ((int) ((percentWidth-100)/2), 0, 100, 100); 더 정확한 것은 입니다. BufferedImage img2 = img.getSubimage ((int) ((percentWidth-100)/2), 0, 100, 100); – Oleg

1

아래에 내 블로그를 읽어 보시기 바랍니다 - 간단한 RGB 파일의 경우

  1. 이 ImageScalr를 사용합니다. ImageIO 클래스는 파일을 읽거나 ImageScalr을 사용하여 축소판을 만듭니다.
  2. RGB + CYMK를 지원하려면 ImageIO 및 JAI (Java Advanced Imaging) API를 사용하여 파일을 읽고 ImageScalr을 사용하여 축소판을 만듭니다.
  3. 당신이 다루는 파일 모드, 컬러 모드를 모른다면, 가장 안전한 옵션은 ImageMagick을 사용하는 것입니다.

여기에 link은 코드 스 니펫으로 완전한 대답을 제공합니다.

1

는 단지 몇 줄이 할 수있는 많은 이미지 프로세싱 프레임 워크를 사용할 수 있습니다. 아래의 예는 Marvin Framework을 사용하여 다른 해상도 (참조 폭으로 주어진 크기)로 축소판을 생성합니다. 세 개의 미리보기 이미지는 92 ms에 생성되었습니다.

입력 :

enter image description here

출력 :

enter image description here

enter image description here

enter image description here

import static marvin.MarvinPluginCollection.*; 

MarvinImage image = MarvinImageIO.loadImage("./res/input.jpg"); 
MarvinImage scaledImage = new MarvinImage(1,1); 

scale(image, scaledImage, 250); 
MarvinImageIO.saveImage(scaledImage, "./res/output_x250.jpg"); 

scale(image, scaledImage, 150); 
MarvinImageIO.saveImage(scaledImage, "./res/output_x150.jpg"); 

scale(image, scaledImage, 50); 
MarvinImageIO.saveImage(scaledImage, "./res/output_x50.jpg"); 
1

스트레칭이나 라이브러리없이 간편하게 축소판을 만들 수 있습니다. PNG의 투명도로도 작동합니다.

public File createThumbnail(String imageUrl, String targetPath) { 
    final int imageSize = 100; 
    File thumbnail = new File(targetPath); 

    try { 
     thumbnail.getParentFile().mkdirs(); 
     thumbnail.createNewFile(); 
     BufferedImage sourceImage = ImageIO.read(new File(imageUrl)); 
     float width = sourceImage.getWidth(); 
     float height = sourceImage.getHeight(); 

     BufferedImage img2; 
     if (width > height) { 
      float scaledWidth = (width/height) * (float) imageSize; 
      float scaledHeight = imageSize; 

      BufferedImage img = new BufferedImage((int) scaledWidth, (int) scaledHeight, sourceImage.getType()); 
      Image scaledImage = sourceImage.getScaledInstance((int) scaledWidth, (int) scaledHeight, Image.SCALE_SMOOTH); 
      img.createGraphics().drawImage(scaledImage, 0, 0, null); 

      int offset = (int) ((scaledWidth - scaledHeight)/2f); 
      img2 = img.getSubimage(offset, 0, imageSize, imageSize); 
     } 
     else if (width < height) { 
      float scaledWidth = imageSize; 
      float scaledHeight = (height/width) * (float) imageSize; 

      BufferedImage img = new BufferedImage((int) scaledWidth, (int) scaledHeight, sourceImage.getType()); 
      Image scaledImage = sourceImage.getScaledInstance((int) scaledWidth, (int) scaledHeight, Image.SCALE_SMOOTH); 
      img.createGraphics().drawImage(scaledImage, 0, 0, null); 

      int offset = (int) ((scaledHeight - scaledWidth)/2f); 
      img2 = img.getSubimage(0, offset, imageSize, imageSize); 
     } 
     else { 
      img2 = new BufferedImage(imageSize, imageSize, sourceImage.getType()); 
      Image scaledImage = sourceImage.getScaledInstance(imageSize, imageSize, Image.SCALE_SMOOTH); 
      img2.createGraphics().drawImage(scaledImage, 0, 0, null); 
     } 
     ImageIO.write(img2, "png", thumbnail); 
    } 
    catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return thumbnail; 
} 
1

필자는 JAI를 사용하여 몇 년 전에 정적 메서드로 클래스를 작성했습니다. Java Advanced Imaging API는 이미지를 다루는 Java에서 가장 신뢰할 수있는 API입니다. 그것은 벡터 보간은 자바 세계에서 포토샵에 가장 가까운 것입니다. 여기에 그것들 중 하나가 있습니다 :

public static ByteArrayOutputStream resize(InputStream inputStream , int IMG_WIDTH, 
     int IMG_HEIGHT) throws Exception { 
    BufferedImage originalImage = ImageIO.read(inputStream); 
    int type = originalImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB 
      : originalImage.getType(); 
    BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, 
      type); 
    { 
     Graphics2D g = resizedImage.createGraphics(); 
     g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null); 
     g.dispose(); 
     g.setComposite(AlphaComposite.Src); 

     g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
       RenderingHints.VALUE_INTERPOLATION_BILINEAR); 
     g.setRenderingHint(RenderingHints.KEY_RENDERING, 
       RenderingHints.VALUE_RENDER_QUALITY); 
     g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 
    } 
    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    ImageIO.write(resizedImage, "png", bos); 
    return bos; 

} 
1

나는 꽤 오래된 게시물이라는 것을 알고 있습니다. 나는 썸네일을 생성하는 솔루션을 찾고 그래서 사용하게 된이

Thumbnails.of(originalImage).scale(0.25).asBufferedImage(); 

는 0.45

Thumbnails.of(originalImage).scale(0.45).asBufferedImage(); 

https://github.com/coobird/thumbnailator

이에 규모를 설정하는 제안 모바일에 사용하는 경우 두 옵션을 모두 테스트 한만큼 Graphics2D를 사용하는 것이 훨씬 빠릅니다.

관련 문제