java - 在不损失质量的情况下调整图像大小

标签 java resize bufferedimage

我编写这段代码是为了根据两个因素调整图像大小。可以用,但是调整大小后图像质量很差!你能帮帮我吗?

这是代码

public class ImageTest {

private static final int factor1 = 3;
private static final int factor2 = 4;
public static void main(String [] args){

    JFileChooser cs = new JFileChooser();
    cs.setFileSelectionMode(cs.DIRECTORIES_ONLY);
    int i = cs.showOpenDialog(null);
    if(i==cs.APPROVE_OPTION){
        File f = cs.getSelectedFile();
        File[] ff = f.listFiles();
        for(int j=0;j<ff.length;j++){
            String end = ff[j].getName().substring(ff[j].getName().indexOf(".")+1);
            System.out.println(end);
            try{
                BufferedImage originalImage = ImageIO.read(ff[j]);
                int type = originalImage.getType() == 0? BufferedImage.TYPE_INT_ARGB : originalImage.getType();
                BufferedImage resizeImageJpg = resizeImageWithHint(originalImage, type);
                ImageIO.write(resizeImageJpg, end, new File("pr/"+ff[j].getName()));
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    }


}
private static BufferedImage resizeImageWithHint(BufferedImage originalImage, int type){
    int IMG_WIDTH = (originalImage.getWidth()*factor1)/factor2;
    int IMG_HEIGHT = (originalImage.getHeight()*factor1)/factor2;
    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);

    return resizedImage;
}   
   }

我在网上看到 resizeImageWithHint 是在范围内完成的,以免降低质量……但确实如此!为什么?你能帮我吗?

最佳答案

关于这个主题我读过的最好的文章是 The Perils of Image.getScaledInstance() (网络存档)。

简而言之:您需要使用多个调整大小步骤才能获得良好的图像。文章中的辅助方法:

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.drawImage(ret, 0, 0, w, h, null);
        g2.dispose();

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

    return ret;
}

关于java - 在不损失质量的情况下调整图像大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7951290/

相关文章:

java - 外部 jar 的 log4j 配置

java - 哪个 jar 和 spring 版本<mvc :resource> come?

java - 带有 HTML 的 JLabel 未正确设置宽度

android - 调整从图库中选取的图像大小

Css float 调整布局

java - 使用 JPanel 时何时创建手动后台缓冲区?

java - 缓冲图像像素操作

java - 从 Selenium IDE 以 Excel 格式记录测试用例

java - 选择具有匹配列名的所有表

java - 如何在 BufferedImage 中设置 XYZ-ColorSpace 像素?