绘制从角落偏移的图像的某些部分? [英] Drawing certain parts of image offset from the corner?

查看:24
本文介绍了绘制从角落偏移的图像的某些部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用各种精灵表来加载宇宙飞船.Graphics.drawImage() 的文档说明参数是

boolean Graphics.drawImage(Image img,内部dstx1,内部dsty1,内部dstx2,内部dsty2,int srcx1、int srcy1、int srcx2、int srcy2、ImageObserver 观察者);

但是文档说dstx1和dsty2是左上角的坐标,当你用dstx2和dsty2指定绘制的区域时,尺寸是(dstx2-dstx1)和(dsty2-dsty1).除非我误解了该功能的工作原理,否则这似乎只会从角落加载图像的一部分.如何绘制未连接到左角的图像的一部分,用于绘制精灵表的不同部分?

解决方案

public abstract boolean drawImage(Image img,国际dx1,int dy1,国际dx2,int dy2,国际sx1,国际 sy1,国际 sx2,国际 sy2,ImageObserver 观察者)

<块引用>

参数:

  • img - 要绘制的指定图像.如果 img 为 null,则此方法不执行任何操作.
  • dx1 - 目标矩形第一个角的 x 坐标.
  • dy1 - 目标矩形第一个角的 y 坐标.
  • dx2 - 目标矩形第二个角的 x 坐标.
  • dy2 - 目标矩形第二个角的 y 坐标.
  • sx1 - 源矩形第一个角的 x 坐标.
  • sy1 - 源矩形第一个角的 y 坐标.
  • sx2 - 源矩形第二个角的 x 坐标.
  • sy2 - 源矩形第二个角的 y 坐标.
  • observer - 随着更多图像的缩放和转换而被通知的对象.

ds 是目的地,意思是你想要在表面上绘制图像的位置.ss 是源图像的坐标.对于两者,第一个角是左上角,第二个角是右下角.

因此您可以将源图像视为要绘制的图像的焦点部分.您可以使用源坐标来确定要提取的矩形区域.

目标坐标布局源区域实际绘制的方式/位置.因此,如果您只想沿 x 轴移动绘制的图像,那么您只需移动 dx1dx2.您实际上可以使用坐标来调整绘制区域的大小,只需指定一个大于或小于源矩形的坐标矩形

 源图像目标面板sx1, sy1+--------------+---------+ +---------------------+||||||地区到|||dx1, dy1 ||画 |||+-----------+ ||||||||+--------------+ ||||||sx2, sy2 ||+-----------+ ||||dx2, dy2 |||||+-------------------------+ +---------------------+

这是一个运行示例.

免责声明:我的计算可能有点偏差.不确定我是否正在捕捉图像的每个部分.刚刚快速完成了这个.

import java.awt.Dimension;导入 java.awt.Graphics;导入 java.awt.event.ActionEvent;导入 java.awt.event.ActionListener;导入 java.awt.image.BufferedImage;导入 java.io.IOException;导入 java.util.logging.Level;导入 java.util.logging.Logger;导入 javax.imageio.ImageIO;导入 javax.swing.JFrame;导入 javax.swing.JPanel;导入 javax.swing.SwingUtilities;导入 javax.swing.Timer;公共类 NerdGirl 扩展 JPanel {私有静态最终 int SPRITE_ROWS = 5;私有静态最终 int SPRITE_COLUMNS = 2;私有静态最终 int 延迟 = 150;私人 int DIM_W;私人 int DIM_H;私有 int x1Src;私有 int y1Src;私有整数 x2Src;私有 int y2Src;私有 BufferedImage img;公共书呆子女孩(){尝试 {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 = new Timer(DELAY, new ActionListener() {public void actionPerformed(ActionEvent e) {if (x1Src >= img.getWidth() - DIM_H - 5) {//5 处理精度损失x1Src = 0;x2Src = x1Src + DIM_W;if (y1Src >= DIM_H - 5) {//5 处理精度损失y1Src = 0;y2Src = y1Src + DIM_H;} 别的 {y1Src += DIM_H;y2Src = y1Src + DIM_H;}} 别的 {x1Src += DIM_W;x2Src = x1Src + DIM_W;}重绘();}});定时器开始();}@覆盖受保护的无效paintComponent(图形g){super.paintComponent(g);g.drawImage(img, 0, 0, getWidth(), getHeight(), x1Src, y1Src, x2Src, y2Src, this);}@覆盖公共维度 getPreferredSize() {返回 (img == null) ?new Dimension(300, 300) : new Dimension(DIM_W, DIM_H);}公共静态无效主(字符串 [] args){SwingUtilities.invokeLater(new Runnable() {公共无效运行(){JFrame frame = new JFrame();frame.add(new NerdGirl());frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);框架.pack();frame.setLocationRelativeTo(null);frame.setVisible(true);}});}}

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 img,
   int dstx1, int dsty1, int dstx2, int dsty2,
   int srcx1, int srcy1, int srcx2, int srcy2,
   ImageObserver observer);

However, the documentation says that dstx1 and dsty2 are the coordinates of the top left corner, and when you use dstx2 and dsty2 to specify the area drawn, the dimensions are (dstx2- dstx1) and (dsty2 - dsty1). Unless I'm misunderstanding how the function works, It appears that this only loads portions of the image form the corner. How could one draw a part of the image that is not connected to the lefthand corner, for drawing different parts of a sprite sheet?

解决方案

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.

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);
            }
        });
    }
}

这篇关于绘制从角落偏移的图像的某些部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆