2013-10-25 25 views
6

Ho un 10000x10000 BufferedImage e sto cercando di disegnare solo una parte di esso per un Canvas, c'è un modo per farlo usando argomenti quali:Come disegnare parte di una grande BufferedImage?

x, y, width, height?

Quindi, ad esempio, drawImage (img, x, y, width, height) disegnerebbe un rettangolo dall'immagine a partire da (x, y) e avendo (larghezza, altezza) come le dimensioni?

EDIT:

ho intenzione di ri-parola a questa domanda:

ho un'immagine di 10000x10000 e voglio solo per visualizzare una porzione di esso sullo schermo, il problema con un solo compensazione esso per x e y è che questo causa ancora lag mentre l'intera immagine viene sottoposta a rendering, solo la maggior parte su tela. Come posso fondamentalmente fare in modo che l'intera immagine sia renderizzata, ma posso scorrere intorno senza causare il ritardo della tela?

+0

Ho modificato la risposta in risposta alla tua domanda. – Sage

risposta

17

Ho un 10000x10000 BufferedImage e sto cercando di disegnare solo una parte di essa ad una tela, c'è un modo per farlo usando argomenti quali:

  1. Non utilizzare la tela per la verniciatura personalizzata in java. utilizzare invece JComponent o JPanel. Ha una bella funzione paintComponent(Graphics g), la sovrascrive e dipinge l'immagine all'interno con g.drawImage(x, y, width, height, observer);

  2. La grafica di rotazione ha Graphics.clipRect(int x, int y, int width, int height) per legare il rettangolo di area a cui si desidera disegnare prima di disegnare l'immagine.

Edit (In risposta alla tua domanda Edited):

Primo approccio è quello di utilizzare BufferedImage..getSubimage(x, y, width, height) per ottenere un'immagine secondaria con la regione rettangolo specificato. È più veloce

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

Questa funzione vi darà una nuova immagine ritagliata con la rectangle(x, y, width, height) dell'immagine originale specificato. Usa l'immagine restituita per disegnare sul tuo componente.

risorsa Tutorial:Clipping the Drawing Region


Demo: Dimostrazione Immagine di ritaglio con animazione:

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

Credo che questo metodo ridimensiona effettivamente l'immagine per adattarla al rettangolo specificato, che non è quello che sto cercando. –

+0

Sì, hai ragione, usa invece: http://docs.oracle.com/javase/6/docs/api/java/awt/Graphics.html#drawImage(java.awt.Image, int, int, int, int, int, int, int, int, java.awt.Color, java.awt.image.ImageObserver) –

0

è possibile ridimensionare o disegnare una parte di un'immagine utilizzando Graphics.drawImage come menzionato un altro a nswer e secondo la documentazione di Java, l'argomento ImageObserver non è necessario per BufferedImage, quindi è sufficiente passare null.

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

Tuttavia, la mia scelta sarebbe il disegno regione dell'immagine, invece di ritaglio. Ecco un esempio che puoi provare:

Graphics2D g = BufferedImage.getGraphics; 
g.setClip(x, y, width, height); 
g.drawImage(sx, sy, x - sx, y - sy, null);