2009-05-03 8 views
12

私は、Java(Spring、Hibernate/JPA、Struts2)で書かれたWebアプリケーションを使用して、ユーザーが画像をアップロードしてファイルシステムに保存することができます。私はそれらのイメージがサイト上に表示するための一貫したサイズになるようにそれらのイメージを拡大したいと思います。最良の結果をもたらすライブラリや組み込み関数はありますか?私は(この順序で)私の決定を行う際に以下の基準を考慮します:Javaで画像を拡大縮小する最も良い方法は何ですか?

  • フリー/オープンソース
  • (基本的な)簡単な結果
  • パフォーマンス
  • サイズの
  • 品質を実装します実行可能ファイル

答えて

4

Java Image I/O APIを読んでイメージを読み書きしてください。次に、AffineTransformを使用してサイズを変更します。

また、here's java.awt.Imageを使用した完全な例です。

+0

あなたが引用している例は、AffineTransformではなく、 'getScaledInstance()'を使っています。それはどちらですか?私は、 'getScaledInstance'がperformantではないという混在したレビューを読んだことがあります... – gdbj

4

java-image-scalingもご覧ください。それはImageIOよりも優れた画像を作り出しました。

0

画像編集に最適なツールはImageMagickで、オープンソースです。

Java言語用の2つのインターフェイスがあります。ImageMagickの

にJNIインタフェースを使用しています

JMagick

im4javaはImageMagickの

9

するためのコマンドラインインターフェースである私は本当にお勧めしますimgscalrをご覧ください。

それはGitHub上でホストされ、Apache 2のライセンスの下でリリースされ、既にWebアプリケーションのほんの一握りに配備されては、非常に単純でありますが、pedantically documented API、透過的にあなたのためのJDKで約2主要なイメージのバグを動作するコードを持っていますスケール操作や恐ろしい結果の後に突然「黒」の画像を取得し始めた場合、Javaで利用可能な最良の結果を得ることができ、MavenとZIPで利用可能であり、単一クラス。

基本的な使用は次のようになります。

BufferedImage img = ImageIO.read(...); // load image 
BufferedImage scaledImg = Scalr.resize(img, 320); 

これはライブラリは、高品質で最高の推測にするあなたの画像の比率を尊重し、320×320バウンディングボックス内の結果をフィットする最も簡単な呼び出しです。注:バウンディングボックスは、使用されるW/Hの最大値にすぎません。画像の比率が高くなるので、結果の画像は320x200と同じです。

自動モードを無効にして見栄えの良い結果を得たい場合や、非常にマイルドなアンチエイリアスフィルタを結果に適用して(特にサムネイルに適している)

BufferedImage img = ImageIO.read(...); // load image 
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY, 
             150, 100, Scalr.OP_ANTIALIAS); 

これらはすべて単なる例であり、APIは幅広く、超簡単な使用例から非常に特殊なものまですべてを網羅しています。あなたは自分のBufferedImageOpsを渡して画像に適用することもできます(そして、ライブラリは自動的に6年間BufferedImageOp JDKのバグを修正します)。

Javaで画像をスケーリングしても、たとえば、サポートされているRGBまたはARGBイメージタイプのうちの1つに常にイメージを保持している間は、そのイメージを操作します。 Java2Dの画像処理パイプラインは、画像操作に使用される画像タイプがあまりサポートされていない場合、劣悪なソフトウェアパイプラインに戻ってしまいます。

私はライブラリを書いてオープンソース化しているので、心配することなくイメージをサイズ変更して自分の生活を変えることができますそれ。

希望に役立ちます。

0

私はimgscalrを標準のJava 1.6と比較しようとしましたが、それはより良いとは言えません。私が試した何

BufferedImage bufferedScaled = Scalr.resize(sourceImage, Method.QUALITY, 8000, height); 

Image scaled = sourceImage.getScaledInstance(-1, height, Image.SCALE_SMOOTH); 
    BufferedImage bufferedScaled = new BufferedImage(scaled.getWidth(null), scaled.getHeight(null), BufferedImage.TYPE_INT_RGB); 
    bufferedScaled.getGraphics().drawImage(scaled, 0, 0, null); 

私の目には、いくつかの5分のテストが第二のもの(ピュアJava 1.6)は、より良い結果を生むという印象を持っています。これはより速くであることが判明

-1

public static BufferedImage getScaledInstance(final BufferedImage img, final int targetWidth, final int targetHeight, 
               final Object hint) { 
    final int type = BufferedImage.TYPE_INT_RGB; 
    int drawHeight = targetHeight; 
    int drawWidth = targetWidth; 
    final int imageWidth = img.getWidth(); 
    final int imageHeight = img.getHeight(); 
    if ((imageWidth <= targetWidth) && (imageHeight <= targetHeight)) { 
     logger.info("Image " + imageWidth + "/" + imageHeight + " within desired scale"); 
     return img; 
    } 
    final double sar = ((double) imageWidth)/((double) imageHeight); 
    if (sar != 0) { 
     final double tar = ((double) targetWidth)/((double) targetHeight); 
     if ((Math.abs(tar - sar) > .001) && (tar != 0)) { 
      final boolean isSoureWider = sar > (targetWidth/targetHeight); 
      if (isSoureWider) { 
       drawHeight = (int) (targetWidth/sar); 
      } 
      else { 
       drawWidth = (int) (targetHeight * sar); 
      } 
     } 
    } 
    logger.info("Scaling image from " + imageWidth + "/" + imageHeight + " to " + drawWidth + "/" + drawHeight); 
    final BufferedImage result = new BufferedImage(drawWidth, drawHeight, type); 
    try { 
     final Graphics2D g2 = result.createGraphics(); 
     try { 
      if (hint != null) { 
       g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); 
      } 
      g2.drawImage(img, 0, 0, drawWidth, drawHeight, null); 
     } 
     finally { 
      g2.dispose(); 
     } 
     return result; 
    } 
    finally { 
     result.flush(); 
    } 
} 
1

私は、これは非常に古い質問ですけど、私は、標準のJava API

import java.awt.*; 
import java.awt.event.*; 
import javax.imageio.* 
import java.awt.image.*; 

BufferedImage im, bi, bi2; 
Graphics2D gfx; 
int imWidth, imHeight, dstWidth, dstHeight; 
int DESIRED_WIDTH = 500, DESIRED_HEIGHT = 500; 

im = ImageIO.read(new File(filePath)); 
imWidth = im.getWidth(null); 
imHeight = im.getHeight(null); 

dstWidth = DESIRED_WIDTH; 
dstHeight = (dstWidth * imHeight)/imWidth; 

bi = new BufferedImage(dstWidth, dstHeight, im.getType()); 

gfx = bi.createGraphics(); 
gfx.drawImage(im, 0, 0, dstWidth, dstHeight, 0, 0, imWidth, imHeight, null); 

bi2 = new BufferedImage(DESIRED_WIDTH, DESIRED_HEIGHT, im.getType()); 
gfx = bi2.createGraphics(); 

gfx.drawImage(bi, 0, 0, DESIRED_WIDTH, DESIRED_HEIGHT, null); 

ImageIO.write(bi2, "jpg", new File(filePath)); 

を使用して、このための私自身のソリューションを持って、私はそれができると確信しています改善され、適応される。

関連する問題