PNG、JPEG、GIFファイルのサイズを変更する必要があります。 Javaを使用してこれを行うにはどうすればよいですか?
画像を読み込んだ後、次を試すことができます:
BufferedImage createResizedCopy(Image originalImage,
int scaledWidth, int scaledHeight,
boolean preserveAlpha)
{
System.out.println("resizing...");
int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
Graphics2D g = scaledBI.createGraphics();
if (preserveAlpha) {
g.setComposite(AlphaComposite.Src);
}
g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();
return scaledBI;
}
FWIW imgscalr ( Maven central で利用可能)と呼ばれるJavaのシンプルな画像スケーリングライブラリをリリースしました(GitHubでホストされているApache 2)。
ライブラリは、画像スケーリングに対していくつかの異なるアプローチを実装し(Chris Campbellのインクリメンタルアプローチといくつかのマイナーな機能強化を含む)、必要に応じて最適なアプローチを選択するか、最速または最高の外観を提供します(お願いします)。
使い方は非常に簡単で、静的メソッドの束にすぎません。最も単純なユースケースは次のとおりです。
BufferedImage scaledImage = Scalr.resize(myImage, 200);
すべての操作は画像の元の比率を維持するため、この場合はimgscalrに幅200ピクセル、高さ200ピクセルの範囲内で画像のサイズを変更するように要求します。デフォルトでは、指定されていません。
最初はこれが自己宣伝のように見えることに気づきましたが、これとまったく同じテーマをグーグルで探して、さまざまな結果/アプローチ/考え/提案を考え出し、座って書くことにしました画像があり、おそらくサムネイルを必要とする80-85%のユースケースに対処する単純な実装-できるだけ速く、または見栄えの良いもの(試した人には気づくでしょう十分な小さな画像へのBICUBIC補間を使用してGraphics.drawImageを実行しても、依然としてゴミのように見えます)。
Thumbnailator は、 MITライセンスの下で配布される、流[なインターフェースを備えたJavaのオープンソースイメージサイズ変更ライブラリです。
Javaで高品質のサムネイルを作成するのは驚くほど難しく、結果のコードはかなり複雑になる可能性があるため、このライブラリを作成しました。 Thumbnailatorを使用すると、シンプルで流APIなAPIを使用して、かなり複雑なタスクを表現できます。
簡単な例
簡単な例として、画像を取得して100 x 100にサイズ変更(元の画像のアスペクト比を保持)し、ファイルに保存すると、1つのステートメントで実現できます。
Thumbnails.of("path/to/image")
.size(100, 100)
.toFile("path/to/thumbnail");
高度な例
複雑なサイズ変更タスクの実行は、Thumbnailatorの流れるようなインターフェイスで簡素化されています。
次のことをしたいとしましょう:
0.85
の品質設定ですべてをJPEGに保存し、thumbnail.
が先頭に追加されたオリジナルから取得されますThumbnailatorに変換すると、次を使用して上記を実行できます。
Thumbnails.of(new File("path/to/directory").listFiles())
.size(100, 100)
.outputFormat("JPEG")
.outputQuality(0.85)
.toFiles(Rename.PREFIX_DOT_THUMBNAIL);
画質と速度に関する注意事項
このライブラリは、高品質のサムネイルを生成するために、チェット・ハーゼとロマン・ガイによる Filthy Rich Clients で強調表示されているプログレッシブ双線形スケーリングメソッドも使用します許容可能な実行時パフォーマンスを確保しながら。
これを行うためにライブラリは必要ありません。 Java自体で実行できます。
Chris Campbellには、画像のスケーリングに関する優れた詳細な説明があります- この記事 を参照してください。
Chet HaaseとRomain Guyの本には、画像スケーリングの詳細かつ非常に有益な記事があります Filthy Rich Clients 。
Java Advanced Imaging はオープンソースになり、必要な操作を提供します。
大きな画像を扱う場合や、見栄えの良い結果が必要な場合は、Javaでの簡単な作業ではありません。 Graphics2Dを介したスケール変更操作を介して単純に実行しても、高品質のサムネイルは作成されません。 JAIを使用してそれを行うことができますが、見栄えの良いものを得るために想像するよりも多くの作業が必要であり、JAIにはOutOfMemoryエラーでJVMを吹き飛ばすという厄介な習慣があります。
ImageMagickを使用できる場合は、ImageMagickを外部実行可能ファイルとして使用することをお勧めします。使い方は簡単で、適切に機能するため、必要はありません。
マシンにimagemagickをインストールするオプションがある場合、 im4Java をお勧めします。これはコマンドラインインターフェイス上の非常に薄い抽象化レイヤーですが、非常にうまく機能します。
Java APIは、画像の標準スケーリング機能および画像品質のダウングレードを提供しません。
このため、JavaCVのcvResizeを使用しようとしましたが、問題が発生するようです。
イメージスケーリングに適したライブラリが見つかりました。pom.xmlに「Java-image-scaling」の依存関係を追加するだけです。
<dependency>
<groupId>com.mortennobel</groupId>
<artifactId>Java-image-scaling</artifactId>
<version>0.8.6</version>
</dependency>
Mavenリポジトリで、これの最新バージョンを取得します。
例Javaプログラム内
ResampleOp resamOp = new ResampleOp(50, 40);
BufferedImage modifiedImage = resamOp.filter(originalBufferedImage, null);
GraphicsMagick Image Processing System を im4Java とともにJavaのコマンドラインインターフェイスとして使用してみてください。
GraphicsMagickには多くの利点がありますが、すべての利点があります。
この種の操作には、Marvin(純粋なJava画像処理フレームワーク)を使用できます。 http://marvinproject.sourceforge.net
スケールプラグイン: http://marvinproject.sourceforge.net/en/plugins/scale.html
Image Magickが言及されました。 JMagickと呼ばれるJNIフロントエンドプロジェクトがあります。それは特に安定したプロジェクトではありません(そしてImage Magick自体は大きく変化し、互換性を壊すことでさえ知られています)。とはいえ、JMagickとImage Magickの互換性のあるバージョンを実稼働環境で使用して、高スループット、低レイテンシレートでスケーリングを実行した良い経験がありました。速度は、以前に試したすべてのJavaグラフィックライブラリを使用した場合よりも大幅に向上しました。
Burkhardの答えを使用しますが、グラフィックを作成した後に次の行を追加します。
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
値をBICUBICに設定することもできます。これにより、より高品質の画像が生成されますが、より高価な操作になります。設定できるレンダリングヒントは他にもありますが、補間によって最も顕著な効果が得られることがわかりました。ズームインする場合は、Javaコードが非常に遅くなる可能性が高いことに留意してください。すべてのレンダリングヒントが品質よりも速度を最適化するように設定されていても、より大きな画像ではズームが約300%遅れることがあります。
パフォーマンスの高いスケーラーを作成するのは簡単ではないことがわかります。私は一度オープンソースプロジェクトのためにそれをしました: ImageScaler 。
原則として「Java.awt.Image#getScaledInstance(int、int、int)」も同様に機能しますが、これには厄介なバグがあります-詳細については私のリンクを参照してください。
インポートしたくない場合 imgScalr @Riyad Kallaの回答のように上記のテストがうまく機能している場合は、 Peter Walser answer @Peter Walser :
/**
* utility method to get an icon from the resources of this class
* @param name the name of the icon
* @return the icon, or null if the icon wasn't found.
*/
public Icon getIcon(String name) {
Icon icon = null;
URL url = null;
ImageIcon imgicon = null;
BufferedImage scaledImage = null;
try {
url = getClass().getResource(name);
icon = new ImageIcon(url);
if (icon == null) {
System.out.println("Couldn't find " + url);
}
BufferedImage bi = new BufferedImage(
icon.getIconWidth(),
icon.getIconHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
// Paint the Icon to the BufferedImage.
icon.paintIcon(null, g, 0,0);
g.dispose();
bi = resizeImage(bi,30,30);
scaledImage = bi;// or replace with this line Scalr.resize(bi, 30,30);
imgicon = new ImageIcon(scaledImage);
} catch (Exception e) {
System.out.println("Couldn't find " + getClass().getName() + "/" + name);
e.printStackTrace();
}
return imgicon;
}
public static BufferedImage resizeImage (BufferedImage image, int areaWidth, int areaHeight) {
float scaleX = (float) areaWidth / image.getWidth();
float scaleY = (float) areaHeight / image.getHeight();
float scale = Math.min(scaleX, scaleY);
int w = Math.round(image.getWidth() * scale);
int h = Math.round(image.getHeight() * scale);
int type = image.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
boolean scaleDown = scale < 1;
if (scaleDown) {
// multi-pass bilinear div 2
int currentW = image.getWidth();
int currentH = image.getHeight();
BufferedImage resized = image;
while (currentW > w || currentH > h) {
currentW = Math.max(w, currentW / 2);
currentH = Math.max(h, currentH / 2);
BufferedImage temp = new BufferedImage(currentW, currentH, type);
Graphics2D g2 = temp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(resized, 0, 0, currentW, currentH, null);
g2.dispose();
resized = temp;
}
return resized;
} else {
Object hint = scale > 2 ? RenderingHints.VALUE_INTERPOLATION_BICUBIC : RenderingHints.VALUE_INTERPOLATION_BILINEAR;
BufferedImage resized = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = resized.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(image, 0, 0, w, h, null);
g2.dispose();
return resized;
}
}
次の人気製品を使用できます。 thumbnailator
私は、GIFアニメーションを処理するために利用可能な無料のクラス(AnimatedGifEncoder、GifDecoder、およびLWZEncoder)を使用したソリューションを開発しました。
jgifcode jarをダウンロードして、GifImageUtilクラスを実行できます。リンク: http://www.jgifcode.com