Drawing certain parts of image offset from the corner?

前端 未结 1 995
悲&欢浪女
悲&欢浪女 2021-01-03 14:31

I\'m using a sprite sheet of sorts to load in spaceships. The documentation of Graphics.drawImage() states the arguments are

boolean Graphics.drawImage(Image         


        
相关标签:
1条回答
  • 2021-01-03 15:28
    public abstract boolean drawImage(Image img,
                                      int dx1,
                                      int dy1,
                                      int dx2,
                                      int dy2,
                                      int sx1,
                                      int sy1,
                                      int sx2,
                                      int sy2,
                                      ImageObserver observer)
    

    Parameters:

    • img - the specified image to be drawn. This method does nothing if img is null.
    • dx1 - the x coordinate of the first corner of the destination rectangle.
    • dy1 - the y coordinate of the first corner of the destination rectangle.
    • dx2 - the x coordinate of the second corner of the destination rectangle.
    • dy2 - the y coordinate of the second corner of the destination rectangle.
    • sx1 - the x coordinate of the first corner of the source rectangle.
    • sy1 - the y coordinate of the first corner of the source rectangle.
    • sx2 - the x coordinate of the second corner of the source rectangle.
    • sy2 - the y coordinate of the second corner of the source rectangle.
    • observer - object to be notified as more of the image is scaled and converted.

    the ds are the destination, meaning where you want the image to be drawn on your surface. The ss are the coordinates of the source image. For both, the first corner being the upper left, and the second corner being the bottom right.

    So you can think of the source image as like a focus section of the image to be drawn. You can use the source coordinates to determine the rectangle region to extract.

    The destination coordinates layout how/where the the source region is actually drawn. So if you just want to move the drawn image along the x axis, then you just move the dx1 and the dx2. You can actually use the coordinates to resize the drawn region, by just specifying a coordinate rectangle larger or smaller than the source rectangle

                Source Image                     Destination panel
     sx1, sy1      
        +---------------+---------+        +-----------------------------+
        |               |         |        |                             |
        | region to     |         |        | dx1, dy1                    |
        |        draw   |         |        |    +----------+             |    
        |               |         |        |    |          |             |
        +---------------+         |        |    |          |             | 
        |           sx2, sy2      |        |    +----------+             |     
        |                         |        |            dx2, dy2         |
        |                         |        |                             |
        +-------------------------+        +-----------------------------+
    

    Here's a running example.

    Disclaimer: My calculations may be a little off. Not sure if I'm capturing each every section of the image. Just whipped this up really quick.

    enter image description here

    enter image description here

    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    
    public class NerdGirl extends JPanel {
        private static final int SPRITE_ROWS = 5;
        private static final int SPRITE_COLUMNS = 2;
        private static final int DELAY = 150;
    
        private int DIM_W;
        private int DIM_H;
    
        private int x1Src;
        private int y1Src;
        private int x2Src;
        private int y2Src;
    
        private BufferedImage img;
    
        public NerdGirl() {
            try {
                img = ImageIO.read(getClass().getResource("/resources/nerd-girl.jpg"));
            } catch (IOException ex) {
                Logger.getLogger(NerdGirl.class.getName()).log(Level.SEVERE, null, ex);
            }
            DIM_W = img.getWidth() / SPRITE_ROWS;
            DIM_H = img.getHeight() / SPRITE_COLUMNS;
            x1Src = 0;
            y1Src = 0;
            x2Src = x1Src + DIM_W;
            y2Src = y1Src + DIM_H;
            Timer timer = new Timer(DELAY, new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    if (x1Src >= img.getWidth() - DIM_H - 5) {  // 5 to take care of precision loss
                        x1Src = 0;
                        x2Src = x1Src + DIM_W;
                        if (y1Src >= DIM_H - 5) { // 5 to take care of precision loss
                            y1Src = 0;
                            y2Src = y1Src + DIM_H;
                        } else {
                            y1Src += DIM_H;
                            y2Src = y1Src + DIM_H;
                        }
    
                    } else {
                        x1Src += DIM_W;
                        x2Src = x1Src + DIM_W;
                    }
    
                    repaint();
                }
            });
            timer.start();
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(img, 0, 0, getWidth(), getHeight(), x1Src, y1Src, x2Src, y2Src, this);
        }
    
        @Override
        public Dimension getPreferredSize() {
            return (img == null) ? new Dimension(300, 300) : new Dimension(DIM_W, DIM_H);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    JFrame frame = new JFrame();
                    frame.add(new NerdGirl());
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    }
    
    0 讨论(0)
提交回复
热议问题