2013-03-21 5 views
12

안녕하세요. QR 코드 이미지가 있습니다.이 코드를 사용하여 작은 이미지의 크기를 조정하려고 할 때 크기를 조정하려고 할 때 항상 불결한 이미지가 표시되고 QR 코드는 스캔 할 때 더 이상 유효하지 않습니다. 내가 같은 코드로 큰 크기의 이미지로 크기를 조정할 때,하지만 잘 작동 :이미지를 자바에서 크기를 조정하는 방법?

public BufferedImage getScaledInstance(BufferedImage img, 
            int targetWidth, 
            int targetHeight, 
            Object hint, 
            boolean higherQuality) 
{ 
int type = (img.getTransparency() == Transparency.OPAQUE) ? 
    BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; 
BufferedImage ret = (BufferedImage)img; 
int w, h; 
if (higherQuality) { 
    // Use multi-step technique: start with original size, then 
    // scale down in multiple passes with drawImage() 
    // until the target size is reached 
    w = img.getWidth(); 
    h = img.getHeight(); 
} else { 
    // Use one-step technique: scale directly from original 
    // size to target size with a single drawImage() call 
    w = targetWidth; 
    h = targetHeight; 
} 

do { 
    if (higherQuality && w > targetWidth) { 
     w /= 2; 
     if (w < targetWidth) { 
      w = targetWidth; 
     } 
    } 

    if (higherQuality && h > targetHeight) { 
     h /= 2; 
     if (h < targetHeight) { 
      h = targetHeight; 
     } 
    } 

    BufferedImage tmp = new BufferedImage(w, h, type); 
    Graphics2D g2 = tmp.createGraphics(); 
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); 
    //  g2.setRenderingHint(RenderingHints.KEY_DITHERING, hint); 
    g2.drawImage(ret, 0, 0, w, h, null); 
    g2.dispose(); 

    ret = tmp; 
} while (w != targetWidth || h != targetHeight); 

return ret; 
} 

문제가 무엇인지, 내가 정확히 이해하지 못하고, 나에게 적어도 힌트를 줄 당신에게

+0

당신은 어떤 보간 힌트를 설정하고 있습니까? –

+0

고맙습니다. 내 보간 힌트는 RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR입니다. 가능한 모든 값을 시도했지만 여전히 작동하지 않습니다. – Walllzzz

답변

23

나는 여기에 내 코드입니다,이 작업을 달성하기 위해 아핀 변환을 사용하는 것이 도움이되기를 바랍니다

@의 A4L의 답변에 따라
/** 
* scale image 
* 
* @param sbi image to scale 
* @param imageType type of image 
* @param dWidth width of destination image 
* @param dHeight height of destination image 
* @param fWidth x-factor for transformation/scaling 
* @param fHeight y-factor for transformation/scaling 
* @return scaled image 
*/ 
public static BufferedImage scale(BufferedImage sbi, int imageType, int dWidth, int dHeight, double fWidth, double fHeight) { 
    BufferedImage dbi = null; 
    if(sbi != null) { 
     dbi = new BufferedImage(dWidth, dHeight, imageType); 
     Graphics2D g = dbi.createGraphics(); 
     AffineTransform at = AffineTransform.getScaleInstance(fWidth, fHeight); 
     g.drawRenderedImage(sbi, at); 
    } 
    return dbi; 
} 
+0

고마워 많이 작동하지만 fWidth 및 fHeight에 넣을 대상은 무엇입니까? 때마다 출력이 달라집니다. – Walllzzz

+1

X 및 Y 축 좌표의 축척 비율은 [javadoc] (http : // docs. oracle.com/javase/6/docs/api/java/awt/geom/AffineTransform.html#getScaleInstance%28double,%20double%29). 예를 들어 결과 이미지를'half' 이미지를 원래 이미지로 만들고 싶다면 fWidth와 fHeight 모두에 '0.5'를 전달하십시오. 값이 1보다 작 으면 1로, 값이 1보다 커지면 1이되어 같은 크기의 이미지가됩니다. – A4L

+0

내 문제를 해결해 주셔서 감사 드리며 모든 답변을 받아 들여 대답으로 선택하겠습니다. – Walllzzz

7

나는 개인적으로 또한 사용하는이 클래스를 썼다. 나는 그 코드가 곧 바랄 것이기를 바랍니다.

import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.Toolkit; 
import java.awt.image.BufferedImage; 
import java.awt.image.CropImageFilter; 
import java.awt.image.FilteredImageSource; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JComponent; 


public class ImageScaler { 

     private ImageIcon originalImage; 
     private ImageIcon scaledImage; 

     public ImageScaler(Image image) { 
       this.originalImage = new ImageIcon(image); 
     } 

     public ImageScaler(String fileName) { 
       originalImage = new ImageIcon(fileName); 
     } 

     public void createScaledImage(int size, ScalingDirection scalingDirection) { 
       if (scalingDirection == ScalingDirection.HORIZONTAL) { 
         scaledImage = new ImageIcon(originalImage.getImage().getScaledInstance(size, -1, Image.SCALE_SMOOTH)); 
       } else { 
         scaledImage = new ImageIcon(originalImage.getImage().getScaledInstance(-1, size, Image.SCALE_SMOOTH)); 
       }  
     } 

     public void createScaledImage(int size, ScalingDirection scalingDirection, int scale) { 
       if (scalingDirection == ScalingDirection.HORIZONTAL) { 
         scaledImage = new ImageIcon(originalImage.getImage().getScaledInstance(size, -1, scale)); 
       } else { 
         scaledImage = new ImageIcon(originalImage.getImage().getScaledInstance(-1, size, scale)); 
       } 
     } 

     public void createScaledImage(int width, int height, ScaleType scaleType) { 
       int imageWidth = originalImage.getImage().getWidth(null); 
       int imageHeight = originalImage.getImage().getHeight(null); 
       double originalImageRatio = imageWidth/(double) imageHeight; 
       double scaledImageRatio = width/(double) height; 

       if(scaleType == ScaleType.FIT) { 
         if(imageHeight - (Math.abs(imageWidth - width)/originalImageRatio) <= height) { 
           scaledImage = new ImageIcon(originalImage.getImage().getScaledInstance(width, -1, Image.SCALE_SMOOTH)); 
         } else if(imageWidth - (Math.abs(imageHeight - height) * originalImageRatio) <= width) { 
           scaledImage = new ImageIcon(originalImage.getImage().getScaledInstance(-1, height, Image.SCALE_SMOOTH)); 
         } 
       } else if(scaleType == ScaleType.FILL) { 
         if(imageHeight - (Math.abs(imageWidth - width)/originalImageRatio) >= height) { 
           scaledImage = new ImageIcon(originalImage.getImage().getScaledInstance(width, -1, Image.SCALE_SMOOTH)); 
           int thumbHeight = scaledImage.getImage().getHeight(null); 

           // Crop the image 
           scaledImage = new ImageIcon(Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(scaledImage.getImage().getSource(), new CropImageFilter(0, (thumbHeight-height)/2, width, height)))); 
         } else if(imageWidth - (Math.abs(imageHeight - height) * originalImageRatio) >= width) { 
           scaledImage = new ImageIcon(originalImage.getImage().getScaledInstance(-1, height, Image.SCALE_SMOOTH)); 
           int thumbWidth = scaledImage.getImage().getWidth(null); 

           // Crop the image 
           scaledImage = new ImageIcon(Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(scaledImage.getImage().getSource(), new CropImageFilter((thumbWidth-width)/2, 0, width, height)))); 
         }    
       } 
     } 

     public void saveScaledImage(File file, ImageType imageType) { 
       if (scaledImage != null) { 
         BufferedImage bi = new BufferedImage(scaledImage.getIconWidth(), scaledImage.getIconHeight(), BufferedImage.TYPE_INT_RGB); 
         Graphics g = bi.getGraphics(); 
         g.drawImage(scaledImage.getImage(), 0, 0, null); 
         try { 
           ImageIO.write(bi, imageType.value(), file); 
         } catch (IOException ioe) { 
           System.out.println("Error occured saving scaled image"); 
         } 
       } else { 
         System.out.println("Scaled image has not yet been created"); 
       } 
     } 

     public void saveOriginalImage(File file, ImageType imageType) { 
       if (originalImage != null) { 
         BufferedImage bi = new BufferedImage(originalImage.getIconWidth(), originalImage.getIconHeight(), BufferedImage.TYPE_INT_RGB); 
         Graphics g = bi.getGraphics(); 
         g.drawImage(originalImage.getImage(), 0, 0, null); 
         try { 
           ImageIO.write(bi, imageType.value(), file); 
         } catch (IOException ioe) { 
           System.out.println("Error occured saving original image"); 
         } 
       } else { 
         System.out.println("Original image has not yet been created"); 
       } 
     } 

     // ENUMS 
     public enum ScalingDirection {VERTICAL, HORIZONTAL}; 
     public enum ScaleType {FIT, FILL}; 
     public enum ImageType { 
       IMAGE_JPEG ("jpeg"), 
       IMAGE_JPG ("jpg"), 
       IMAGE_PNG ("png"); 

       private String value = null; 

       ImageType(String value) { 
         this.value = value; 
       } 

       String value() { 
         return value; 
       } 
     }; 
} 
+0

고맙습니다. 위의 코드가 작동했기 때문에 고맙습니다. 다른 사람들이 시도해 보도록하겠습니다. – Walllzzz

1
public static BufferedImage resizeImg(BufferedImage img, int newW, int newH) 
    { 
    int w = img.getWidth(); 
    int h = img.getHeight(); 
    BufferedImage dimg = new BufferedImage(newW, newH, img.getType()); 
    Graphics2D g = dimg.createGraphics(); 
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
      RenderingHints.VALUE_INTERPOLATION_BILINEAR); 
    g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null); 
    g.dispose(); 
    return dimg;  
    } 
+1

이 코드가 OP 문제를 해결하는 방법에 대한 자세한 정보를 제공하십시오. 이 코드가 어떻게 도움이되는지는 명확하지 않습니다. – aravind

5

:

더 straigt 앞으로 버전. 또한 그의 솔루션은 이미지 자체가 아닌 캔버스의 크기를 조정했습니다.

public static BufferedImage scale(BufferedImage imageToScale, int dWidth, int dHeight) { 
     BufferedImage scaledImage = null; 
     if (imageToScale != null) { 
      scaledImage = new BufferedImage(dWidth, dHeight, imageToScale.getType()); 
      Graphics2D graphics2D = scaledImage.createGraphics(); 
      graphics2D.drawImage(imageToScale, 0, 0, dWidth, dHeight, null); 
      graphics2D.dispose(); 
     } 
     return scaledImage; 
    } 

는 나에게 자바 여러 단계의 접근 방법보다 더 나은 품질의 이미지를 주었기 때문에 나는 Thumbnailnator 추천

graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 
graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
+0

단순함이 유머러스하다. 고맙습니다. – Apostolos

+0

품질을 높이려면 원하는 원하는 크기에 도달 할 때까지 몇 가지 작은 단계로 스캘링을 수행하는 것이 좋습니다. – A4L

+0

사실, "프로그레시브 스케일링"이라고합니다 - 여기에서 설명 드리겠습니다 : http://stackoverflow.com/questions/24745147/java-resize-image-without-losing-quality/36367652#36367652 Campbell의 블로그에 기초 : https : // community.oracle.com/docs/DOC-983611 – for3st

0

사실입니다 참조하십시오. 새로운 BufferedImage를 생성 할 필요는 없습니다. for3st에서 언급 한 메서드를 원본 BufferedImage 이미지 ('image')에 직접 적용하고 원하는 너비와 높이를 설정할 수 있습니다. 따라서 하나의 문장 만 필요합니다 (자바 문서의 표준에 포함됨) :

drawImage(BufferedImage image, int x, int y, int width, int height, ImageObserver observer) 
관련 문제