2013-10-25 5 views
6

は私が10000x10000 BufferedImage持っていると私はCanvasへの一部だけを描画しているよ、のような引数を使ってこれを行う方法はありますか?大きなBufferedImageの一部を描画する方法は?</p> <p><code>x, y, width, height</code>:

たとえば、drawImage(img、x、y、width、height)は(x、y)から始まり、幅、高さを次元として持つイメージから矩形を描画しますか?

編集:私は言葉にこの質問再つもり

を私は10000x10000イメージを持っていると私は、画面上での部分を表示したい、それを相殺するとの問題xとyの違いは、画像全体がレンダリングされているときにはまだラグが発生していて、そのほとんどはキャンバスから外れているということです。画像全体がレンダリングされるように基本的にはできますが、キャンバスを遅らせることなくスクロールできます。

+0

あなたの質問に対する回答を編集しました。 – Sage

答えて

17

私は10000x10000たBufferedImageと私はキャンバスに、それの一部のみ を描画するために探しています持っている、などの引数を使ってこれを行う方法があります:

  1. javaでカスタムペイントにキャンバスを使用しないでください。代わりにJComponentまたはJPanelを使用してください。それは素晴らしい機能を持っていますpaintComponent(Graphics g)、それをオーバーライドし、g.drawImage(x, y, width, height, observer)であなたのイメージをペイントします。

  2. スインググラフィックは、画像を描画する前に描画する領域の矩形を連結するために​​になります。

編集(編集した質問に対して):

最初のアプローチは、指定した矩形領域とサブ画像を取得するためにBufferedImage..getSubimage(x, y, width, height)を使用することです。それはより速いです。

BufferedImage img = ImageIO.read(new File("file")); 
    img = img.getSubimage(50, 50, 500, 500); // 500 x 500 

この機能を使用すると、指定された元画像のrectangle(x, y, width, height)とクロップあなたに新しいイメージを与えます。返されたイメージを使用してコンポーネントに描画します。

チュートリアルリソース:Clipping the Drawing Region


デモ:アニメーションで画像をクリッピング実証:

enter image description here

import java.awt.*; 
import java.awt.event.*; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.net.URL; 
import java.util.*; 
import java.util.logging.*; 
import javax.imageio.ImageIO; 
import javax.swing.*; 
import javax.swing.Timer; 

class MyCanvas extends JPanel implements ActionListener 
{ 
    public BufferedImage buffImg; 
    public Rectangle rectangle; 
    Random random; 
    long lastTimeChanged; 
    int dirX = 1, dirY = 1; 
    volatile static boolean imageLoading = true; 
    public MyCanvas() { 
     random = new Random(); 
     rectangle = new Rectangle(50, 50, 250, 250); 
     lastTimeChanged = System.currentTimeMillis(); 
     setBackground(Color.WHITE); 
    } 


    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     if(imageLoading) 
     { 
      showWaitForLoading(g); 
      return; 
     } 

     g.clipRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height); 
     g.drawImage(buffImg, 0, 0, getWidth(), getHeight(), this); 

    } 


    public void showWaitForLoading(Graphics g) 
    { 
     Graphics2D g2d = (Graphics2D)g.create(); 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.setColor(Color.DARK_GRAY); 
     g2d.fillRoundRect(getWidth()/2-100, getHeight()/2-15, 200, 30, 30, 30); 
     g2d.setColor(Color.WHITE); 
     g2d.drawString("Loading image...", getWidth()/2 - 45, getHeight()/2 + 3); 
     g2d.dispose(); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 

     long endTime = System.currentTimeMillis(); 
     if(endTime - lastTimeChanged > 500) 
     { 
      dirX = random.nextInt(2) == 0 ? -1 : 1; 
      dirY = random.nextInt(2) == 0 ? -1 : 1; 
      lastTimeChanged = endTime; 
     } 

     if(rectangle.x < 0)dirX = 1; 
     else if(rectangle.x + rectangle.width > getWidth())dirX = -1; 

     if(rectangle.y < 0)dirY = 1; 
     else if(rectangle.y + rectangle.height > getHeight())dirY = -1; 

     rectangle.x = rectangle.x + dirX * 10; 
     rectangle.y = rectangle.y + dirY * 10;; 

     repaint(); 
    } 

} 
public class CustomPainting { 


    public static void main(String[] args) throws IOException { 

     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       final MyCanvas canvas = new MyCanvas(); 
       JFrame frame = new JFrame(); 
       frame.setSize(new Dimension(500, 500)); 
       frame.add(canvas); 
       frame.setVisible(true); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

       Timer timer = new Timer(200, canvas); 
       timer.start(); 
       new Thread() 
       { 
        public void run() 
        { 
         try { 
          canvas.buffImg = ImageIO.read(new URL("http://images6.fanpop.com/image/photos/33400000/Cute-Panda-beautiful-pictures-33434826-500-500.jpg")); 
          MyCanvas.imageLoading = false; 
         } catch (IOException ex) { 
          Logger.getLogger(CustomPainting.class.getName()).log(Level.SEVERE, null, ex); 
         } 
        } 
       }.start(); 
      } 
     }); 
    } 
} 
0
+0

私は、このメソッドが実際に指定された矩形の内側に収まるように画像を拡大すると考えています。これは私が探しているものではありません。 –

+0

はい、正しくて、代わりにこれを使用してください:http://docs.oracle.com/javase/6/docs/api/java/awt/Graphics.html#drawImage(java.awt.Image、int、int、int、 int、int、int、int、java.awt.Color、java.awt.image.ImageObserver) –

0

あなたが使用して画像の一部を拡大縮小または描くことができますGraphics.drawImageはもう1つのJavaのドキュメントによると、ImageObserverの引数はBufferedImageでは必要ないので、nullを渡すことができます。

http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html

しかし、私の選択ではなく、画像の描画領域のクリッピングになります。 次の例は試してみることができます:

Graphics2D g = BufferedImage.getGraphics; 
g.setClip(x, y, width, height); 
g.drawImage(sx, sy, x - sx, y - sy, null); 
関連する問題