2012-02-06 15 views
0

私は、ユーザーが自分のプロフィール画像に使用する画像をトリミングするためのシンプルなクラスを実装しようとしています。これはJava Webアプリケーションです。JavaのBufferedImageの代替画像

私はいくつかの検索を行い、java.awtにBufferedImageクラスがあり、これが(一見して)私に必要なものに完璧であることがわかります。しかし、これはクロップが正しく機能するとは限らないことを意味するバグ(またはおそらくjavaと思われます)があるようです。 (

BufferedImage profileImage = getProfileImage(form, modelMap); 
    if (profileImage != null) { 
     BufferedImage croppedImage = profileImage 
       .getSubimage(form.getStartX(), form.getStartY(), form.getWidth(), form.getHeight()); 
     System.err.println(form.getStartX()); 
     System.err.println(form.getStartY()); 
     File finalProfileImage = new File(form.getProfileImage()); 
     try { 
      String imageType = getImageType(form.getProfileImage()); 
      ImageIO.write(croppedImage, imageType, finalProfileImage); 
     } 
     catch (Exception e) { 
      logger.error("Unable to write cropped image", e); 
     } 
    } 
    return modelAndView; 
} 

protected BufferedImage getProfileImage(CropImageForm form, Map<String, Object> modelMap) { 
    String profileImageFileName = form.getProfileImage(); 
    if (validImage(profileImageFileName) && imageExists(profileImageFileName)) { 
     BufferedImage image = null; 
     try { 
      image = getCroppableImage(form, ImageIO.read(new File(profileImageFileName)), modelMap); 
     } 
     catch (IOException e) { 
      logger.error("Unable to crop image, could not read profile image: [" + profileImageFileName + "]"); 
      modelMap.put("errorMessage", "Unable to crop image. Please try again"); 
      return null; 
     } 
     return image; 
    } 

    modelMap.put("errorMessage", "Unable to crop image. Please try again."); 
    return null; 
} 

private boolean imageExists(String profileImageFileName) { 
    return new File(profileImageFileName).exists(); 
} 

private BufferedImage getCroppableImage(CropImageForm form, BufferedImage image, Map<String, Object> modelMap) { 
    int cropHeight = form.getHeight(); 
    int cropWidth = form.getWidth(); 
    if (cropHeight <= image.getHeight() && cropWidth <= image.getWidth()) { 
     return image; 
    } 
    modelMap.put("errorMessage", "Unable to crop image. Crop size larger than image."); 
    return null; 
} 

private boolean validImage(String profileImageFileName) { 
    String extension = getImageType(profileImageFileName); 
    return (extension.equals("jpg") || extension.equals("gif") || extension.equals("png")); 
} 

private String getImageType(String profileImageFileName) { 
    int indexOfSeparator = profileImageFileName.lastIndexOf("."); 
    return profileImageFileName.substring(indexOfSeparator + 1); 
} 

フォームは、このコードスニペットで呼ばトリミングを開始するには、左上隅の整数値を含む単純なPOJOである:ここでは

は、私は私の画像をトリミングしようとする使用していたコードがありますstartXとstartY)、幅と高さを指定して新しい画像を作成します。

しかし、私は結局、startXとstartYの位置ではなく0,0で始まるトリミングされたイメージです。私は適切な値がgetSubimageメソッドに渡されていることを確認するためにコードを検査しました。

画像の切り抜きにBufferedImageを使用する簡単な方法はありますか?私はJAIを簡単に見てきました。私はむしろすべてのプロダクションボックスにインストールされているjdkを更新するだけでなく、開発/テストサーバーとローカルワークステーションにアプリケーションを追加することもできます。

代替手段を選択するための基準は次のとおりです。 1)これはすべて私が のために使用する画像です。2)JavaまたはSpringに組み込まれていない場合は、ウェブアプリケーションにデプロイ可能

何か提案がありますか?

注:BufferedImageのやJavaの問題は、私はこの投稿で見たものだったがあることを上記のコメント:Guidance on the BufferedImage.getSubimage(int x, int y, int w, int h) method?

+2

これまで問題なく、 'getSubImage(...)'を使ってきました。おそらく、私たちは最初に、エラーがJavaにあり、あなたのコードではないことを確かめてから、いくつかの難解な選択肢を見つけようとします。あなたの問題を示すが、問題とは無関係のコードは存在しない、コンパイル可能で実行可能な最小限のプログラムである[sscce](http://sscce.org)を作成し投稿することを検討してください。 –

+0

イメージを取得して切り抜くためのコードを追加しました。私はフォームオブジェクトを除外しました。これは、上で述べたように、ファイル名を持つPOJOとトリミングの座標です。 –

+0

コード帳をありがとう、うまくいけば、人々がチェックし、まともな解決策を与えるのに十分である。そうでない場合は、[sscce](http://sscce.org)の作成と投稿を再度検討してください。 Aaginは誰もあなたのコードの残りの部分を見たいと思っていますが(投稿してくれないことに感謝します)、上記の方法の問題を示す小型のコンパイル可能なテストプログラムが大きな助けになります。 –

答えて

0

ありがとう:あなたは完全に新しい、独立したBufferedImageをしたい場合は

最良の方法は、単に全体でそれを描くことです。問題はクロッピングコードにはまったくないことが判明しました。

トリミングする画像を表示したときに、レイアウトにうまく収まるように画像のサイズを変更した後、ジャバスクリプトのトリミングツールを使用してトリミングする座標を見つけました。

クロッピング座標を決定するときにイメージのサイズを変更していたが、サイズ変更を考慮しなかったので、左上隅と一致するように見える座標で終わった。

画像のサイズを変更しないように表示を変更しましたが、現在はクロップが美しく機能しています。

+0

さらに1つのアップデート。このメソッドでgifイメージを切り抜く場合、Javaにバグがあります。開始点のx座標とy座標の入力に関係なく、左上隅から常に始まるように見えます。これは最初の質問(リンクはhttp://bugs.sun.com/view_bug.do?bug_id=6795544) –

+0

に記載されているバグで参照されています。問題が発生しても、あなたのバグはあなたのプログラムのバグに起因していました。上記にリンクされたバグは、赤ちゃんだった。 –

+0

はい、私の問題は私のコードのバグであったことに同意します。私は明確にその状態を持っています。私が他の問題を言及した理由は、何か類似しているかもしれない人を助けることです。 BufferedImageコードにgifイメージのみのバグがあることを明確にし、コード内のバグについて説明することで、他の誰かが同様の問題を自分のコードで診断するのを助けることができます。 –

1

あなたもこの方法でそれを行うことができます(コードは、私が採用として試験100%ではありません例えば、既存のアプリから):

2

何度も問題なくgetSubimage()を何度も使用しています。その呼び出しの前にSystem.out.println(form.getStartX()+ "" + form.getStartY())を追加して、両方が0でないことを確認しましたか?

また、少なくともimage.getWidth()x form.getHeight()を取得していますか?

返されたBufferedImageが親と同じデータ配列を共有するため、profileImageを変更/廃棄していないことを確認してください。回答者全員に対して

BufferedImage croppedImage = new BufferedImage(form.getWidth(),form.getHeight(),BufferedImage.TYPE_INT_ARGB); 

Graphics g = croppedImage.getGraphics(); 
g.drawImage(profileImage,0,0,form.getWidth(),form.getHeight(),form.getStartX(),form.getStartY(),form.getWidth(),form.getHeight(),null); 
g.dispose();