5

ある画像の一部を別の小さな画像にコピーしたい、つまり、サブ長方形をコピーしたい。

ソース用のGraphics2Dオブジェクトがあり、ターゲット用に作成でき、targetGraphics2D.drawImage(Image img,....)について知っていますが、 sourceGraphics2Dからそのimgを取得するにはどうすればよいですか?


回答 (aioobe ごと): ソースはGraphics2DではなくImageである必要があります。

Image.subImage()は、ソースの関連部分を取得するためのメソッドです。

4

4 に答える 4

3

簡単な答え: はい、できます

バッファリングされた Image で作成された 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 で機能するとは限りません。少なくともアプローチを示しており、実際のクラスを調べてフィールドを取得する必要がある場合があります。

于 2010-12-06T15:04:44.003 に答える
3

Aioobe が言ったように、Graphics2D だけから画像を取得することはできません。ただし、sourceGraphics2D が Swing コンポーネントからのものである場合は、独自の Graphics2D インスタンスでそのペイント メソッドを呼び出してみることができます。そこから、興味深いサブリージョンをコピーできます。

これは一種のハックですが、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);
       }
}
于 2010-12-06T14:57:27.337 に答える
0

まず、以下の Andreas_D の回答に関するメモ:

  • sun.java2d.SunGraphics2D彼のコードは、ドキュメント化されていない内部の OpenJDK クラスに依存しています。つまり、あなたのコンピューターでコンパイルして実行することはできますが、コードを他の人に配布すると壊れる可能性があります。詳細な議論については、これに関する公式声明を参照してください。

  • コードはリフレクションに依存して内部クラスをこじ開けますが、これはそれ自体がコードの匂いです。

  • 全体として、彼のアプローチは非常に悪い習慣の例です(プログラミング スタイルに関しても、仲間のプログラマーが API を正しく使用するのを助けることに関しても)。


からそのimgを取得するにはどうすればよいsourceGraphics2Dですか?

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

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

したがって、おそらくご存じのとおり、Graphics2DAPI には、基になるイメージを取得するためのメソッドが用意されていません。(このような方法は意味がありません。グラフィックス オブジェクトが線を渡し、テキストがプリンターに描画される可能性があります!)

サブイメージを取得するには、指定されたグラフィックス オブジェクトが描画する下のイメージを取得する必要があります。

于 2010-12-06T14:07:16.343 に答える