如何在java中调整图像大小?

你好我有一个二维码图片,我想resize,当我尝试使用这个代码将其调整为一个小图像时,我总是得到一个blury图像,当我扫描它时,二维码不再有效,但是当我使用相同的代码调整大尺寸图像时,它工作正常:

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

有什么问题,我不太明白,请给我至少一个提示,谢谢

我使用仿射变换来完成这个任务,这是我的代码,希望它有所帮助

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

我写了这个我个人也使用的课程。 我希望代码是直截了当的。

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

基于@ A4L的答案:

一个更直接的版本。 他的解决方案也只是缩放canvas而不是图像本身。

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

提高你可以添加的质量

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

请检查一下Image.getScaledInstance()详细信息可以在这个答案中找到: 如何提高g.drawImage()方法的性能来调整图像大小

希望能帮助到你

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

我推荐Thumbnailnator,因为它给了我比Java多步骤方法更高质量的图像。 然而,使用Graphics2D drawImage代码的速度可能会更好。

另请参阅Java – 调整图像大小而不会降低质量

事实上,解决方案更加简单。 您不必创建新的BufferedImage。 您可以将for3st提到的方法直接应用于原始BufferedImage图像(’image’)并设置您希望的宽度和高度。 因此,只需要一个语句(包含在stadard Java文档中):

 drawImage(BufferedImage image, int x, int y, int width, int height, ImageObserver observer)