【问题标题】:Java 2D and resizeJava 2D 和调整大小
【发布时间】:2010-10-07 06:52:51
【问题描述】:

我想重用一些旧的 Java 2D 代码,但想知道这是获得最高质量图像的最佳方式吗?

    public static BufferedImage getScaled(BufferedImage imgSrc, Dimension dim) {

    //  This code ensures that all the pixels in the image are loaded.
    Image scaled = imgSrc.getScaledInstance(
            dim.width, dim.height, Image.SCALE_SMOOTH);

    // This code ensures that all the pixels in the image are loaded.
    Image temp = new ImageIcon(scaled).getImage();

    // Create the buffered image.
    BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), 
            temp.getHeight(null), BufferedImage.TYPE_INT_RGB);

    // Copy image to buffered image.
    Graphics g = bufferedImage.createGraphics();
    // Clear background and paint the image.
    g.setColor(Color.white);
    g.fillRect(0, 0, temp.getWidth(null),temp.getHeight(null));
    g.drawImage(temp, 0, 0, null);
    g.dispose();


    // j2d's image scaling quality is rather poor, especially when
    // scaling down an image to a much smaller size. We'll post filter  
    // our images using a trick found at 
    // http://blogs.cocoondev.org/mpo/archives/003584.html
    // to increase the perceived quality....
    float origArea = imgSrc.getWidth() * imgSrc.getHeight();
    float newArea = dim.width * dim.height;
    if (newArea <= (origArea / 2.)) {
        bufferedImage = blurImg(bufferedImage);
    }

    return bufferedImage;
}

public static BufferedImage blurImg(BufferedImage src) {
    // soften factor - increase to increase blur strength
    float softenFactor = 0.010f;
    // convolution kernel (blur)
    float[] softenArray = {
            0,              softenFactor,       0, 
            softenFactor, 1-(softenFactor*4), softenFactor, 
            0,              softenFactor,       0};

    Kernel kernel = new Kernel(3, 3, softenArray);
    ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
    return cOp.filter(src, null);
}

【问题讨论】:

    标签: java image resize 2d image-scaling


    【解决方案1】:

    您可以使用 JAI(Java 高级成像)来获得更复杂的图像大小调整选项。见https://jai.dev.java.net/。这些比 java.awt.image 包更灵活。

    【讨论】:

      【解决方案2】:

      Chris Campbell 有一篇关于缩放图像的出色而详细的文章 - 请参阅 this article

      Chet Haase 和 Romain Guy 在他们的书 Filthy Rich Clients 中也有关于图像缩放的详细且内容丰富的文章。

      【讨论】:

        【解决方案3】:

        您也可以查看java-image-scaling 库。

        【讨论】:

          【解决方案4】:

          在此处添加一些澄清信息。

          不,这不是在 Java 中获得好看的缩放图像的最佳方法。 Java2D 团队不推荐使用 getScaledInstance 和底层的 AreaAveragingScaleFilter,取而代之的是一些更高级的方法。

          如果您只是想获得一个好看的缩略图,那么可以使用 David 建议的 Chris Campbell 方法。值得一提的是,我已经在名为imgscalr(Apache 2 许可证)的 Java 图像缩放库中实现了该算法以及其他两种更快的方法。该库的重点是在一个易于使用的高度优化库中专门解决这个问题:

          BufferedImage thumbnail = Scalr.resize(srcImg, 150);
          

          为了在 Java 中获得最佳的缩放实例,方法调用应如下所示:

          BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY, 
                                                 150, 100, Scalr.OP_ANTIALIAS);
          

          该库将使用 Java2D 团队推荐的增量缩放方法缩放原始图像,然后将非常温和的卷积运算应用于图像以使其看起来更好,从而有效地对其进行轻微的抗锯齿处理。这对于小缩略图来说非常好,对于大图像来说不是那么重要。

          如果您以前没有使用过 convolveops,那么要获得外观完美的内核以使 op 在所有用例中看起来都很好,就需要做很多工作。 Scalr 类上定义的 OP 常量是与巴西的一个社交网站合作一周的结果,该网站推出了 imgscalr 来处理其成员的个人资料图片。我们来回尝试了 10 种不同的内核,直到我们找到了一个足够细微的内核,不会使图像看起来柔和或模糊,但仍能平滑像素值之间的过渡,因此图像看起来不会“锐利”和噪点小尺寸。

          如果您想要 最好看 缩放图像而不考虑速度,请遵循 Juha 的使用 java-image-scaling 库的建议。它是一个非常全面的 Java2D Ops 集合,包括对 Lanczsos algorithm 的支持,这将为您提供最好的结果。

          我会远离 JAI,不是因为它不好,而是因为它只是一个与您要解决的问题不同/更广泛的工具。前面提到的 3 种方法中的任何一种都可以为您提供漂亮的缩略图,而无需以更少的代码行将全新的成像平台添加到您的项目中。

          【讨论】:

            【解决方案5】:

            您可以使用开源库调整图像大小 enter link description here

            我已经将大图像调整为小图像,结果非常好,保持了良好的纵横比。

            import java.awt.image.BufferedImage;
            import java.io.File;
            import javax.imageio.ImageIO;
            import javax.swing.JOptionPane;
            import org.imgscalr.*;
            import org.imgscalr.Scalr.Method;
            
            
            public class ImageScaller {
            static String SRC_FILES_PATH = "I:\\BigGreen\\";
            static String IMAGE_FILE_PATH = "I:\\Resized\\";
            public ImageScaller() {         
            }   
            public static void main(String[] args) {
                // TODO Auto-generated method stub
                try
                {
                    ResizeLoad(SRC_FILES_PATH);
                }
                catch(Exception ex)
                {
                    System.out.println(ex.toString());
                }
            }
            public static int ResizeLoad(String path)
            {
                String file;
                File folder ;
                File[] listOfFiles = null;       
                listOfFiles = null;
                try
                {           
                    folder = new File(path);
                    listOfFiles = folder.listFiles();   
            
                    for (int i = 0; i < listOfFiles.length; i++)                    
                    {                   
                        if (listOfFiles[i].isFile())
                        {
                            file = listOfFiles[i].getName();
                            ScalledImageWrite(listOfFiles[i].getPath(),file);                                   
                            //System.out.println(file);
                            }
                        }
                    System.out.println("All Resized");
                    }
            
                catch (Exception e) 
                  {
                      JOptionPane.showMessageDialog(null,e.toString(),"Resize & Load :Exception",JOptionPane.WARNING_MESSAGE);                
                  }
                return listOfFiles.length;
            }
            private static File ScalledImageWrite(String path,String fileName) 
              {
                  try
                  {
                      BufferedImage img = ImageIO.read(new File(path));            
                      BufferedImage scaledImg = Scalr.resize(img, Method.AUTOMATIC, 24, 24);                 
                      File destFile = new File(IMAGE_FILE_PATH + fileName);      
                      ImageIO.write(scaledImg, "png", destFile);                  
                      //System.out.println("Done resizing");
                      return destFile;
                  }
                  catch (Exception e) 
                  {
                      JOptionPane.showMessageDialog(null,e.toString(),"Scalled Images Write: Exception",JOptionPane.WARNING_MESSAGE);
                      return null;
                  }
              }
            
            }
            

            这是此代码的图形格式输出。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-02-20
              • 1970-01-01
              • 2013-03-05
              • 1970-01-01
              相关资源
              最近更新 更多