4

再利用したい古いJava2Dコードがいくつかありますが、これが最高品質の画像を取得するための最良の方法であるかどうか疑問に思いました。

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

5 に答える 5

4

Chris Campbell は、画像のスケーリングについて優れた詳細な記事を書いています。この記事を参照してください。

Chet Haase と Romain Guy も、彼らの著書Filthy Rich Clientsで、画像のスケーリングに関する詳細で非常に有益な記事を書いています。

于 2009-02-12T21:41:43.920 に答える
3

ここにいくつかの明確な情報を追加します。

いいえ、それはJava で見栄えの良いスケーリングされた画像を取得する最良の方法ではありません。getScaledInstance と基礎となる AreaAveragingScaleFilter の使用は、Java2D チームによって非推奨になり、より高度なメソッドが優先されます。

見栄えの良いサムネイルを取得しようとしているだけの場合は、David が提案した Chris Campbell の方法を使用することをお勧めします。価値のあるものとして、 imgscar (Apache 2 ライセンス)と呼ばれる Java 画像スケーリング ライブラリに、他の 2 つのより高速な方法と共にそのアルゴリズムを実装しました。ライブラリのポイントは、使いやすい高度に調整されたライブラリでこの質問に具体的に対処することでした。

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

Java で可能な限り最適なスケーリングされたインスタンスを取得するには、メソッド呼び出しは次のようになります。

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

このライブラリは、Java2D チームが推奨するインクリメンタル スケーリング アプローチを使用して元の画像をスケーリングし、さらに見栄えを良くするために、非常に穏やかな畳み込み演算を画像に適用し、効果的にわずかにアンチエイリアシングします。これは、小さいサムネイルでは非常に便利ですが、巨大な画像ではそれほど重要ではありません。

以前に convolveops を使用したことがない場合、op がすべてのユースケースで見栄えがするように完璧に見えるカーネルを取得するだけでも大変な作業です。Scalr クラスで定義された OP 定数は、ブラジルのソーシャル ネットワーキング サイトとの 1 週間のコラボレーションの結果です。このサイトは、メンバーのプロフィール写真を処理するために imgscalr を展開しました。10 の異なるカーネルのようなものを行ったり来たりして、イメージが柔らかくぼやけて見えないようにするのに十分微妙であるが、ピクセル値間の遷移を滑らかにして、イメージが「シャープ」でノイズのように見えないようにするものを見つけるまで試しました。小さなサイズで。

速度に関係なく、最適なスケーリングされた画像が必要な場合は、Java-image-scaling ライブラリを使用するという Juha の提案に従ってください。Java2D Ops の非常に包括的なコレクションであり、最も見栄えの良い結果をもたらすLanczsos アルゴリズムのサポートが含まれています。

それが悪いからではなく、あなたが解決しようとしているものとは異なる/より広いツールだからです。前述の 3 つのアプローチのいずれかを使用すると、まったく新しいイメージング プラットフォームをプロジェクトに追加する必要なく、より少ないコード行で見栄えの良いサムネイルが得られます。

于 2011-02-06T17:32:18.197 に答える
2

JAI(Java Advanced Imaging)を使用して、より高度な画像サイズ変更オプションを取得できます。https://jai.dev.java.net/を参照してください。これらにより、java.awt.imageパッケージよりもはるかに柔軟性が高くなります。

于 2009-02-12T20:45:32.697 に答える
1

You could also look into java-image-scaling library.

于 2010-05-13T10:20:29.527 に答える
1

オープンソース ライブラリを使用して画像のサイズを変更でき ます ここにリンクの説明を入力してください

大きな画像から小さな画像への変更を行ったところ、縦横比を適切に保ちながら優れた結果が得られました。

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

}

このコードの画像形式の出力を次に示します。 ここに画像の説明を入力

于 2013-06-20T12:56:58.743 に答える