7

JavaJAIで画像を拡大縮小する必要があります。現時点では、次のコードを使用しています。

private static RenderedOp scale(RenderedOp image, float scale) {
    ParameterBlock scaleParams = new ParameterBlock();
    scaleParams.addSource(image);
    scaleParams.add(scale).add(scale).add(0.0f).add(0.0f);
    scaleParams.add(Interpolation.getInstance(Interpolation.INTERP_BICUBIC_2));

    // Quality related hints when scaling the image
    RenderingHints scalingHints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    scalingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
    scalingHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    scalingHints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
    scalingHints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
    scalingHints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    scalingHints.put(JAI.KEY_BORDER_EXTENDER, BorderExtender.createInstance(BorderExtender.BORDER_COPY));

    return JAI.create("scale", scaleParams, scalingHints);
}

残念ながら、これは非常に悪い結果につながります。特に、倍率が0.5未満の画像を拡大縮小する必要があるためです...

何かアドバイス?

4

3 に答える 3

16

大きな画像をサムネイルサイズに縮小しようとしているのか、それとも元の画像と拡大縮小された画像と同じくらい大きな違いがあるのでしょうか。

もしそうなら、このトピックは、2007年にJava2DのChris Campbellによって実際に取り上げられました(これを知っているとは思っていませんが、一般的な質問であることを指摘するだけです)。新しいJava2Dスケーリングアプローチ(RenderingHints.VALUE_INTERPOLATION_ *)はそうではなかったからです。当時廃止されたImage.getScaledInstance(SCALE_AREA_AVERAGINGまたはSCALE_SMOOTH)アプローチと同等のものを提供します。

結局のところ、古いJava 1.1 Image.getScaledInstanceアプローチのSCALE_AREA_AVERAGINGまたはSCALE_SMOOTHアプローチは、見栄えの良い画像を生成するためにバックグラウンドで多くの作業を行っていた、かなり高価なマルチステップ操作でした。

クリスは、Java2Dを使用してこれと同じ結果を得る新しい「正しい」方法は、目的の画像サイズに達するまで、できれば次のような高品質のスケールを使用して、画像を半分に何度もスケーリングする増分プロセスであると指摘しました。 RenderHints.VALUE_INTERPOLATION_BICUBICまたはBILINEAR。

結果は、人々が望んでいる元のImage.getScaledInstanceアプローチとほぼ同じになります。

私は実際に数か月前に画像ホスティングサービスを書いているときにこの答えを探しに行きましたが、「Javaで見栄えの良いサムネイルを作成するにはどうすればよいですか?」という単純な質問がいかに複雑であるかに驚いていました。なりました。

私は最終的に、Chrisが提案したインクリメンタルアプローチを含む「ベストプラクティス」を使用して、Javaでの画像スケーリングに対する3つの異なるアプローチを実装する小さなJavaライブラリ(Apache 2、オープンソース)を作成します。

ライブラリはimgscalrと呼ばれます。ダウンロードして、次のように簡単に使用できます。

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

設定して使用するオプションは他にもありますが(スケーリングの品質や速度など)、すぐに使用できるインテリジェントなデフォルト設定により、見栄えの良いスケーリングされた画像を作成できるため、心配する必要はありません。したくない。ライブラリはまた、絶対に必要ではないオブジェクトの割り当てを破棄して回避し、必要がない場合はBufferedImageインスタンスをすぐに破棄するように強力な努力を払っています。これは、長時間実行されるサーバーアプリの一部としてコード化することを目的としているため、致命的。

私はすでにライブラリのいくつかのリリースを作成しました。「良いもの」を取り除いて自分で何かをしたい場合は、それを試してみてください。それはすべてGitHubにあり、どれも最高の秘密ではなく、人々の生活を楽にするための試みにすぎません。

お役に立てば幸いです。

于 2011-02-06T17:04:42.137 に答える
3

私はThumbnailatorで良い結果を得ました。JAI.KEY_BORDER_EXTENDERが何をするのかわかりませんが、残りの機能(アンチエイリアス、ディザリングなど)はサポートされていると思います。かなり大きな白黒画像のグレースケールサムネイルを生成するために使用しました

于 2011-06-29T18:05:53.037 に答える
1

運が良ければ、白黒画像しかない場合は、非常に高速で高品質の操作を使用できます:SubsampleBinaryToGray

于 2012-08-29T10:26:50.187 に答える