2010-12-06 25 views
5

ある画像の一部を別の小さな画像にコピーしたいとします。つまり、部分矩形をコピーします。イメージの一部を別のイメージにコピーするにはどうすればよいですか?

私はソースののGraphics2Dオブジェクトを持って、私は、ターゲットの1を作ることができる、と私は約targetGraphics2D.drawImage(画像IMG、....)を知っているが、どのように私はIMGことを得るのですかsourceGraphics2Dから? (aioobeあたり)


回答:ソースは、イメージなくのGraphics2Dする必要があります。

Image.subImage()は、ソースの関連部分を取得する方法です。

+2

は、サブイメージが()基礎となるをコピーしないことに注意してください画像データ、少なくともBufferedImageしたがって、subImage()によって取得されたImageを描画する場合は、オリジナルを変更し、target.createGraphics()。drawImage(Image img、...)を使用して実際にコピーを作成します。 – Trilarion

答えて

0

まず、Andreas_Dは、以下の答えに関するいくつかの注意事項:

  • 彼のコードは、内部および文書化されていないOpenJDKのクラスであるsun.java2d.SunGraphics2Dに依存しています。つまり、コードを他の人に配布すると、 になる可能性があります。詳細な説明は、official statementを参照してください。

  • コードは内部でコードの匂いである内部のクラスを読み込むためにリフレクションに依存しています。

    すべてのすべてで
  • 、彼のアプローチは、非常に悪い習慣の一例である(両方とも、それはプログラミングスタイルに来るとき、それは仲間のプログラマが正しくAPIを使用することを助けることに来るとき)


sourceGraphics2Dからこのimgを入手するにはどうすればよいですか?

あなたはGraphics2Dクラスの責任を誤解していると思われます。

Graphics2Dクラスを使用して何かを描画します。これは、BufferedImage(バッファリングされたイメージからグラフィックスオブジェクトを取得した場合)、画面(paintComponentメソッドの引数として取得した場合)、またはプリンタで描画することができます。つまり、Graphics2Dのオブジェクトがあると、イメージが存在しないことさえあります。

ご存じのように、Graphics2D APIでは、下にある画像を取得する方法は提供されていません。 (そのような方法は意味をなさないでしょう、グラフィックスオブジェクトは、ラインとテキストがプリンタに描画される行とテキストを渡すかもしれません!)

サブイメージを取得するには、与えられたグラフィックスオブジェクト引き寄せます。

+0

OK、わかりました。ソースは、Graphics2DではなくImageである必要があります。 ImageImage()はクリップを取得するメソッドです。 –

+0

はい。それのようなもの:-) – aioobe

+2

ああ、それは常に方法があります! (そして、この場合、「鉛筆」はそれが何を描いたのかを記憶しています;-)) –

3

Aioobe氏によると、あなたはGraphics2Dだけでイメージを取得するつもりはありません。しかし、sourceGraphics2DがSwingコンポーネントから来ている場合は、独自のGraphics2Dインスタンスを使用してpaintメソッドを呼び出すことができます。そこから興味深いサブ領域をコピーすることができます。

これはハックのようですが、あなたがSwingオブジェクトを使用していると仮定して動作するはずです。

class CopySwingPaintingSubRegion extends TheSourceType 
{ 
     private BufferedImage bufImg; 

     public CopySwingPaintingSubRegion() 
     { 
      bufImg = new BufferedImage(...); 

      //Draw the original image into our bufImg for copying 
      super.paintComponent(bufImg.createGraphics()); 
     } 

     public BufferedImage getSubImage(int x, int y, int w, int h) 
     { 
      return bufImg.getSubImage(x,y,w,h); 
     } 
} 
3

短い答えは:はい、あなたはバッファリングされたイメージ上で作成された

A Graphics2Dオブジェクトは、画像を知っているが、あなたに戻って、それを手に喜んではないことができます。あなたが反射を気にしないなら、それを盗む(反射する)ことができます。

public class Graphics2DReflector { 

    public static void main(String[] args) { 
    // prepare the Graphics2D - note, we don't keep a ref to the image! 
    final Graphics2D g2d = 
      new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB).createGraphics(); 
    g2d.drawString("Reflected", 10, 50); 


    JFrame frame = new JFrame("Reflected Image"); 
    // one Panel to show the image only known by g2d 
    frame.getContentPane().add(new Panel() { 
     @Overwrite 
     public void paint(Graphics g) { 
     try { 
      SurfaceData data = ((SunGraphics2D) g2d).surfaceData; 
      Field bufImg = BufImgSurfaceData.class.getDeclaredField("bufImg"); 
      bufImg.setAccessible(true); 
      BufferedImage image = (BufferedImage) bufImg.get(data); 
      g.drawImage(image,0,0,null); 
     } catch (Exception oops) { 
      oops.printStackTrace(); 
     } 
     } 
    }); 
    frame.setSize(200,200); 
    frame.setVisible(); 
    } 
} 

注:これはいくつかのSun/Oracleクラスによって異なり、すべてのJava VMでは機能しない可能性があります。少なくとも、アプローチを示しているので、実際のクラスを調べてフィールドを取得する必要があるかもしれません。

+1

'sun。*'パッケージと同じ回答の反映に依存しています。 'Graphics2D'オブジェクトは実際には*' SunGraphics2D'ですか? [なぜ開発者がプロ​​グラムを書くべきでないのかを読む] その 'sun'パッケージを呼び出す(http://java.sun.com/products/jdk/faq/faq-sun-packages.html)。 – aioobe

+1

@aiobe - ねえ、それはハックだし、私はすでにその制限のための一般的なメモを追加しました。あなたはistがうまくいかず、私はちょうど答えました:あなたは可能です。ポータブルではありませんが、不可能ではありません。 –

1

私が正しく理解すれば、W3Schoolsにはキャンバスに置く画像の一部を取得するコードがあります。あなたが別のイメージとしてそれを必要とするなら、あなたはそのキャンバスからそれを得ることができます。

は、私が10「セルまたはフレームを」持っている200ワイドで20背の高いPNGイメージを持っている - 私はアニメーションに使用すると、以下の方法を使用します。

context.drawImage(img, sx, sy, swidth, sheight, x, y, width, height); 
関連する問題