2013-10-25 7 views
6

У меня есть 10000x10000 BufferedImage, и я ищу, чтобы сделать только часть его в Canvas, есть способ сделать это, используя арг такие как:Как нарисовать часть большого BufferedImage?

x, y, width, height?

Так, например, drawImage (img, x, y, width, height) будет рисовать прямоугольник из изображения, начинающегося с (x, y) и имеющего (ширину, высоту) в качестве размеров?

EDIT:

Я собираюсь повторно слово на этот вопрос:

У меня есть 10000x10000 изображение, и я только хочу, чтобы отобразить часть его на экране, проблема с просто компенсируя его по x и y состоит в том, что это все еще вызывает отставание по мере того, как весь образ визуализируется, просто большая часть его холста. Как я могу в основном сделать это так, чтобы все изображение было визуализировано, но я могу прокручивать его, не заставляя холст отставать?

+0

Я отредактировал ответ с ответом на ваш вопрос. – Sage

ответ

17

У меня есть 10000x10000 BufferedImage, и я ищу, чтобы сделать только часть его на холсте, есть способ сделать это с помощью арг, таких как:

  1. Не использовать холст для индивидуальной окраски в java. используйте вместо этого JComponent или JPanel. Он имеет приятную функцию paintComponent(Graphics g), переопределяет и рисует ваше изображение внутри с помощью g.drawImage(x, y, width, height, observer);

  2. Swing graphics имеет Graphics.clipRect(int x, int y, int width, int height), чтобы связать прямоугольник области, в который вы хотите нарисовать, прежде чем рисовать изображение.

Edit (В ответ на ваш вопрос отредактированной):

Первый подход заключается в использовании 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) исходного изображения вы указали. Используйте возвращаемое изображение для рисования на вашем компоненте.

Tutorial ресурс: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, int, java.awt.Color, java.awt.image.ImageObserver) –

0

Вы можете масштабировать или нарисовать часть изображения, используя Graphics.drawImage, как упоминалось выше, a nswer и согласно документации 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); 
Смежные вопросы