この質問は少し前に尋ねられたと思いますが、他の誰かがまだこれに遭遇している場合に備えて。
サムネイルがお尻のように見える理由は、2つの原因(主に最初のもの)が原因です。
- Javaでの非インクリメンタルな画像スケーリングは非常に粗く、大量のピクセルデータをスローし、レンダリングのヒントに関係なく結果を1回平均します。
- Java2D(通常はGIF)でサポートが不十分なBufferedImageタイプを処理すると、見栄えが非常に悪くなり、結果がディザリングされる可能性があります。
古いAreaAveragingScaleFilterは見栄えの良いサムネイルを作成するのに適切な仕事をしますが、Java2Dチームによって遅く、非推奨になっています-残念ながら、彼らはそれをすぐに使える素敵な代替品に置き換えず、私たちを残しました私たち自身のようなものです。
Chris Campbell(Java2Dチームの)は、数年前にインクリメンタルスケーリングの概念でこれに対処しました。1回の操作で開始解像度から目標解像度に移行する代わりに、段階的に実行すると、結果がはるかに良くなります。
このためのコードがかなり大きいことを考えると、私はすべてのベストプラクティスをimgscalrというライブラリに書き込み、Apache2ライセンスの下でリリースしました。
最も基本的な使用法は次のようになります。
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, 640);
このユースケースでは、ライブラリはいわゆる「自動」スケーリングモードを使用し、結果の画像を640x640のバウンディングボックス内に収めます(プロポーションを尊重します)。したがって、画像が正方形ではなく、標準の4:3画像である場合は、サイズが640x480に変更されます。引数は最大のサイズです。
Scalrクラスには他にも多数のメソッドがあり(すべて静的で使いやすい)、すべてを制御できます。
可能な限り見栄えの良いサムネイルの場合、コマンドは次のようになります。
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY,
150, 100, Scalr.OP_ANTIALIAS);
Scalr.OP_ANTIALIASはオプションですが、多くのユーザーは、Javaで十分に小さいサムネイルに縮小すると、ピクセル値間の遷移の一部が少し離散的すぎて、画像が「シャープ」に見えると感じています。サムネイルを少し柔らかくする方法を求めたユーザーの数。
これはConvolveOpを介して行われ、これまで使用したことがない場合は、使用する適切な「カーネル」を見つけようとするのは...お尻の痛みです。そのOP_ANTIALIAS定数は、ブラジルのソーシャルネットワークにimgscalrをデプロイした別のユーザー(プロフィール写真のスケーリングに使用)で1週間テストした後、クラスで最も見栄えの良いアンチエイリアシング操作として定義されました。みんなの生活を少し楽にするために入れました。
また、これらすべての例に加えて、GIFやその他の種類の画像(BMP)を拡大縮小すると、拡大縮小された結果が元の画像と比べてひどく見えることがあります...これは、画像のサポートが不十分なためです。 BufferedImageタイプとJava2Dは、ハードウェアアクセラレーションパイプラインの代わりにソフトウェアレンダリングパイプラインを使用するようにフォールバックし、より適切にサポートされるイメージタイプを実現します。
imgscalrがすべてを処理し、それを回避するためにサポートされている最適な画像タイプで画像を保持します。
とにかく、それは「imgscalrを使用してすべてを行うことができ、何も心配する必要がない」という非常に長い言い方です。