5

ImageVoodooプラグインを使用してJRuby/Railsアプリでアップロードされた画像のサムネイルを作成しようとしています。問題は、サイズ変更されたサムネイルが...お尻のように見えることです。

サムネイルを生成するコードは、補間レンダリングヒントを「バイキュービック」に設定するためにすべてを正しく実行しているようですが、開発環境(OS X)または本番Webサーバー(Linux)ではそれらを尊重していません。

サムネイルを生成するコードを抽出し、補間レンダリングヒントを明示的に「バイキュービック」に設定して、ストレートJavaアプリとして書き直し(つまり、main()メソッドから開始)、(の欠如)を再現しました。バイキュービックおよびバイリニアのサイズ変更。

OS XとLinuxの両方で予想されるように、サムアニルは醜くピクセル化されていますが、Windowsでは、バイキュービック補間を使用して画像のサイズを適切に変更します。

JVM環境設定や、それを機能させるために不足している追加のライブラリはありますか?私はこれのために壁に対して頭をたくさん叩いています。

4

4 に答える 4

5

この質問は少し前に尋ねられたと思いますが、他の誰かがまだこれに遭遇している場合に備えて。

サムネイルがお尻のように見える理由は、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を使用してすべてを行うことができ、何も心配する必要がない」という非常に長い言い方です。

于 2011-07-05T16:18:16.530 に答える
1

多分これはあなたのための解決策ですか?

public BufferedImage resizeImage(BufferedImage source, int width, int height)
{
     BufferedImage result = new BufferedImage(widht, height, BufferedImage.TYPE_INT_ARGB);
     Graphics g = result.getGraphics();
     g.drawImage(source, 0, 0, widht, height, null);
     g.dispose();
     return result;
}
于 2009-09-09T11:28:07.737 に答える
0

結局、ImageVoodooの最新バージョンにアップグレードすると、品質が向上したようです。

ソースコードを見ると、ファンキーなAWTレンダリングを実行していて、それを引き出しているように見えます。厄介ですが、うまくいくようです。

それでもImageMagickほど良くはありませんが、以前よりは良くなっています。

于 2009-11-17T00:07:14.180 に答える
0

@Riyad、インクリメンタルスケーリングのコードは「まともな大きさ」ではなく、非常に小さいです(2007年の投稿からわかるように、http://today.java.net/pub/a/today/2007/04 / 03 / perils-of-image-getscaledinstance.html#creating-scaled-instances)他のオプションを提供するライブラリを持つことは有用かもしれませんが、ライブラリを使用するためのライブラリを作成することは意味がありません。

于 2012-07-03T02:49:39.570 に答える