Javaを使用して画像のサイズを変更するにはどうすればよいですか?


126

PNG、JPEG、GIFファイルのサイズを変更する必要があります。Javaを使用してこれを行うにはどうすればよいですか?


14
ライブラリを要求したので、本当の答えはここにあります:stackoverflow.com/questions/244164/…。受け入れられた回答のコードよりもはるかに使いやすいです;)
Artur Gajowy

ライブラリの部分に同意しません:Graphics2Dはawtライブラリの一部であり、オープンソースです。最後の部分(オープンソース)については100%確実ではありませんが、とにかく誰がawtコードを見るのでしょうか。
Burkhard

回答:


87

画像を読み込んだ後、試すことができます:

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

9
このテクニックを使用すると、自分のニーズに対して十分な品質ではないイメージが作成されることがわかりました。
morgancodesは、

1
Image.getScaledInstance(width、height、hints)も行いますか?
コードプレイ、2011年

1
preserveAlphaは間違った方法でチェックしていますか(imageTypeの場合)?
ティロ

@morgancodesに同意します。画質は、同じサイズにサイズ変更すると、OS Xプレビューなどで得られるものよりもはるかに悪くなります。いくつかのオープンソースライブラリを試して、うまく機能するかどうかを確認します。
Thilo

1
「いくつかのオープンソースライブラリを試して、うまく機能するかどうかを確認します。」@RiyadKallaの回答からのimgscalrの+1。
Thilo、2012

182

FWIW私はimgscalrMavenセントラルで利用可能)と呼ばれるJava用のシンプルな画像スケーリングライブラリ(GitHubでホストされているApache 2)をリリースしました)。

ライブラリは、イメージスケーリングにいくつかの異なるアプローチを実装し(いくつかのマイナーな機能強化を伴うChris Campbellのインクリメンタルアプローチを含む)、要求に応じて最適なアプローチを選択するか、最速または最高の見た目を提供します(それを求める)。

使い方は非常に単純で、静的メソッドの集まりです。最も単純なユースケースは次のとおりです。

BufferedImage scaledImage = Scalr.resize(myImage, 200);

すべての操作で画像の元の縦横比が維持されるため、この場合、imgscalrに幅200ピクセル、高さ200ピクセルの範囲内で画像のサイズを変更するように要求します。指定されていません。

私は最初、これは自己宣伝のように見えます(そうです)が、これとまったく同じ主題をググるのにかなりの時間を費やし、さまざまな結果/アプローチ/考え/提案を思いついて、座って書くことを決めました画像があり、おそらくそのサムネイルが必要な場合に、80〜85%のユースケースに対処する単純な実装-可能な限り高速または見栄えの良いもの(試したものについては、十分に小さい画像へのBICUBIC補間を使用してGraphics.drawImageを実行しても、ゴミのように見えます)。


1
Riyad、Scalrを使うのが好きだった。知りたいのですが、静的メソッドをすべて備えたAPIをどのように選んだのですか?私はビルダーに近い同様のapiを書きました。のようにnew ImageScaler(img).resizeTo(...).rotate(...).cropTo(...).toOutputBuffer()。私もあなたのやり方が好きで、もっと簡単だと思います。
Amir Raminfar

4
私はそれがだと思ったので、アミールは、Builderパターンは同様にライブラリのこれらのタイプのために素晴らしい作品、私は静的メソッドのアプローチで行くことに起こった本来は(新しいユーザーと私はimgscalrから予想される使用パターンのために従うことが容易単一のサイズ変更メソッドのみ)状態を保持するインスタンス(ビルダーインスタンス)を使用することによるメリットはありませんでした。そのため、オブジェクトのインスタンス化を保存し、静的メソッドを使用しました。回避できるあらゆる場所で、imgscalr内のオブジェクト作成に対して強いスタンスをとっています。どちらのアプローチも優れています。
リヤードカラ

5
中央のMavenリポジトリでこれを利用できるようにするための+1!
Grilse

このBufferedImageクラスとは何ですか、なぜandroid studioはそれを見つけられないのですか?@Riyad Kalla
Milad

3
@ xe4me BufferedImageは、生の非圧縮ピクセルデータを表すために使用されるJ2SE JDK(Java2Dフレームワークの一部)のクラスです。Androidでは使用できません。Androidには、画像データを操作するための独自のクラスが用意されています。
リヤドカラ2015年

54

Thumbnailatorは、MITライセンスの下で配布される、流れるようなインターフェイスを備えたJava用のオープンソースの画像サイズ変更ライブラリです

私がこのライブラリを作成したのは、Javaで高品質のサムネイルを作成するのが意外に難しく、結果のコードがかなり面倒になる可能性があるためです。Thumbnailatorを使用すると、単純なFluent APIを使用してかなり複雑なタスクを表現できます。

簡単な例

簡単な例として、画像を取得して100 x 100にサイズ変更し(元の画像の縦横比を維持)、ファイルに保存すると、1つのステートメントで実行できます。

Thumbnails.of("path/to/image")
    .size(100, 100)
    .toFile("path/to/thumbnail");

高度な例

複雑なサイズ変更タスクの実行は、Thumbnailatorの流暢なインターフェイスによって簡素化されます。

次のことを実行するとします。

  1. ディレクトリ内の画像を取得し、
  2. 元の画像のアスペクト比で100 x 100にサイズを変更し、
  3. すべてをJPEGに保存し、品質設定を 0.85
  4. ここで、ファイル名はthumbnail.最初から追加された元のファイル名から取得されます

Thumbnailatorに変換すると、次のようにして上記を実行できます。

Thumbnails.of(new File("path/to/directory").listFiles())
    .size(100, 100)
    .outputFormat("JPEG")
    .outputQuality(0.85)
    .toFiles(Rename.PREFIX_DOT_THUMBNAIL);

画質と速度に関する注意

このライブラリは、Chet HaaseとRomain GuyによってFilthy Rich Clientsで強調されたプログレッシブバイリニアスケーリングメソッドも使用して、許容可能なランタイムパフォーマンスを確保しながら高品質のサムネイルを生成します。


1
coobird、APIを使った本当に素晴らしい仕事。非常に簡単で使いやすい。
Riyad Kalla

@LordT:Thumbnailatorが使いやすいとわかって良かったです:)
coobird '13 / 07/13

500x400の元の画像で80x80のサムネイルを作成するにはどうすればよいですか?選択肢はありませんでした。ありがとう!
テリー

「.outputFormat( "JPEG")」は、ドキュメントのどこにも書かれていません。
Vincent Cantin 2013

Thumbnailator APIドキュメントにある使用可能なメソッドの一覧を@Vincent - thumbnailator.googlecode.com/hg/javadoc/net/coobird/...を
coobird

12

これを行うためにライブラリは必要ありません。Java自体でそれを行うことができます。

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

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


7
Chrisの記事は、そもそもimgscalrを書く動機となったものです。そして、このような質問(そしてあなたのような答え)。多くの人々が何度も何度も何度も何度も何度も何度も何度も何度も画像から見栄えの良いサムネイルを取得する方法。それを行うにはいくつかの方法がありますが、クリスは常に最良の方法であるとは限りません。それは、あなたが何をしようとしているのか、そしてどれほどの削減が行われるかに依存します。imgscalrはそのすべてに対応し、1つのクラスです。
リヤドカラ

2
+1、同意します。フィルシーリッチのクライアントは、「効果的なJava」に匹敵する最高のJavaブックの1つですが、私は怠惰なのでImgScalrを使用しています。
Shawn Vader 14


9

大きな画像を処理している場合や見栄えの良い結果が必要な場合は、Javaの簡単な作業ではありません。Graphics2Dを介してrescale opを介して単純に行うと、高品質のサムネイルが作成されません。JAIを使用してそれを行うことができますが、見栄えの良いものを得るには想像以上に多くの作業が必要であり、JAIはOutOfMemoryエラーでJVMをブローするという厄介な習慣を持っています。

ImageMagickを使用できる場合は、外部実行可能ファイルとして使用することをお勧めします。使い方は簡単で、正しく機能するので、必要はありません。


4

マシンにimagemagickをインストールするオプションがある場合は、im4javaをお勧めします。これは、コマンドラインインターフェイスの非常に薄い抽象化レイヤーですが、非常にうまく機能します。


3

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

GitHub(github.com/mortennobel/java-image-scaling.git)からも入手でき、現時点ではバージョン8.7です。pom.xmlのli'l修正が必要です(新しいMavenでは1.5がサポートされなくなったため、ソースとターゲットを少なくとも1.6に変更してください)。
Cromax 2018年

2

あなたは使用することを試みることができるGraphicsMagickの画像処理システムをしてim4java Java用COMANDラインインターフェイスとして。

GraphicsMagickには多くの利点がありますが、すべてに1つあります。

  • GMは、世界最大の写真サイト(FlickrやEtsyなど)で数十億のファイルを処理するために使用されます。

1

Image Magickが言及されました。JMagickと呼ばれるJNIフロントエンドプロジェクトがあります。これは特に安定したプロジェクトではありません(Image Magick自体が大幅に変更され、互換性が失われることさえ知られています)。とは言っても、本番環境でJMagickと互換バージョンのImage Magickを使用して、高スループット、低レイテンシレートでスケーリングを実行した経験は豊富です。速度は、以前に試したすべてのJavaグラフィックライブラリよりも大幅に優れていました。

http://www.jmagick.org/index.html


1

Burkhardの答えを使用するだけですが、グラフィックを作成した後に次の行を追加します。

    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

値をBICUBICに設定することもできます。これにより、画像の品質が向上しますが、操作のコストが高くなります。設定できるレンダリングヒントは他にもありますが、補間によって最も顕著な効果が得られることがわかりました。ズームインしたい場合は、Javaコードが非常に遅くなる可能性が高いことに注意してください。すべてのレンダリングヒントが品質よりも速度を最適化するように設定されていても、大きな画像では300%前後のズームの遅れが生じます。



1

高性能のスケーラーを作成することは簡単ではないことがわかります。オープンソースプロジェクトImageScalerで1回実行しました

原則として、「java.awt.Image#getScaledInstance(int、int、int)」も機能しますが、これには厄介なバグがあります。詳細については、私のリンクを参照してください。


0

私は、GIFアニメーションの処理に使用できる無料で利用できるクラス(AnimatedGifEncoder、GifDecoder、およびLWZEncoder)を使用してソリューションを開発しました。
jgifcode jarをダウンロードして、GifImageUtilクラスを実行できます。リンク:http : //www.jgifcode.com


1
あなたがあなたが推薦する製品と提携しているなら、答えで言及してください。
Hans Olsson、2012

うわー...それはGIFアニメーション画像のサイズを変更するためのものですか?そしてそれは無料ですか?うわぁ...今から試してみよう...
gumuruh

はい、これは私が開発しました。これがgithub.com/rt29/jgifcodeのソースコードです-これは今ここにあります。もうサポートしていません。
Rohit Tiwari 2015年


0

インポートしたくない場合はimgScalr私がテストした上@Riyadカラの答えはあまりにも罰金を作品のように、あなたはこれはから取らないことができますピーター・ヴァルザーの答えかかわらず、別の問題に@Peterヴァルザー:

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

0

次の方法を試してください:

ImageIcon icon = new ImageIcon("image.png");
Image img = icon.getImage();
Image newImg = img.getScaledInstance(350, 350, java.evt.Image.SCALE_SMOOTH);
icon = new ImageIcon(img);
JOptionPane.showMessageDialog(null, "image on The frame", "Display Image", JOptionPane.INFORMATION_MESSAGE, icon);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.