简体   繁体   English

如何使用AffineTransform旋转位图

[英]How to rotate a bitmap with AffineTransform

I'm trying to create a simple program that displays a bitmap zombie picture and then rotates it around using AffineTransform and Thread. 我试图创建一个简单的程序,显示位图僵尸图片,然后使用AffineTransform和Thread旋转它。 I followed the example I had to accomplish this, but whenever I run the program the zombie bitmap just rotates once and stops. 我按照必须完成此操作的示例进行操作,但是无论何时运行程序,僵尸位图都只会旋转一次并停止。 Also, for some reason when I painted the zombie bitmap, the image is partially off the screen along the y-axis. 另外,由于某种原因,当我绘制僵尸位​​图时,图像沿y轴部分不在屏幕上。

So my questions are: why is the bitmap not rotating and why is the bitmap off the screen. 所以我的问题是:为什么位图不旋转以及为什么位图不在屏幕上。

Code is as follows: 代码如下:

import java.awt.*;// Graphics class
import java.awt.geom.*;
import java.net.*;//URL navigation
import javax.swing.*;//JFrame
import java.util.*;//Toolkit

public class BitMapZombies2 extends JFrame implements Runnable
{
    private Image zombieOneRight;
    Thread zombieRun;


    public static void main (String[] args)
    {
        new BitMapZombies2();
    }

    public BitMapZombies2()
    {
        super("Bit Map Zombies..RUN FOR YOUR LIFE!!!");
        setSize(800,600);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Toolkit Zkit = Toolkit.getDefaultToolkit();

        zombieOneLeft = Zkit.getImage(getURL("_images/_production_images/zombie_1_left_75h.png"));
        zombieOneRight = Zkit.getImage(getURL("_images/_production_images/zombie_1_right_75h.png"));

        zombieRun = new Thread(this);
        zombieRun.start();

    }

    AffineTransform zombieIdentity = new AffineTransform();

    private URL getURL(String filename)
    {
        URL url = null;
        try
        {
            url = this.getClass().getResource(filename);
        }
        catch (Exception e) {}
        return url;
    }

    public void paint(Graphics z)
    {
        Graphics2D z2d = (Graphics2D) z;
        AffineTransform ZombiePowered = new AffineTransform();

        z2d.setColor(Color.BLACK);
        z2d.fillRect(0,0, 800, 600);

        ZombiePowered.setTransform(zombieIdentity);
        ZombiePowered.rotate(2,37.5,37.5);
        z2d.drawImage(zombieOneRight,ZombiePowered,this);
    }

    public void run()
    {
        Thread zT = Thread.currentThread();
        while (zT == zombieRun)
        {
            try
            {

                Thread.sleep(500);
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }

            repaint();
        }
    }


        }

Appreciate any help I can get on this. 感谢我可以为此提供的任何帮助。

Once you've created your transformation, you need to apply it to the graphics context... 创建转换后,需要将其应用于图形上下文...

public void paint(Graphics z)
{
    //...
    z2d.setTransform(ZombiePowered);
    //...
}

Once you apply a transformation, it will effect everything painted to the Graphics context after it so you need to reset it or referse it. 一旦应用了变换,它将影响绘制在Graphics上下文之后的所有内容,因此您需要重置或引用它。 There's lots of ways to do this, but the simplest would be to create a copy of the Graphics context and simply dispose of it when you no longer need it... 有很多方法可以做到这一点,但是最简单的方法是创建Graphics上下文的副本,并在不再需要它时disposedispose ...

public void paint(Graphics z)
{
    Graphics2D z2d = (Graphics2D) z.create();
    //...
    z2d.dispose();
}

Also, this is just me, but I'd be creating a new instance of the AffineTransform , these things are to easy to completely screw up... 另外,这只是我,但是我将创建AffineTransform的新实例,这些事情很容易完全搞定……

Commenting your code: 注释您的代码:

    AffineTransform ZombiePowered = new AffineTransform();//Create an Id. transform
    ZombiePowered.setTransform(zombieIdentity);//Set it as a copy of an Id. transform
    ZombiePowered.rotate(2, 37.5, 37.5);//Concatenate the rotation with the Id. transform
    z2d.drawImage(zombieOneRight, ZombiePowered, this);//Apply the rotation

So your always rotating 2rads your image. 因此,您始终旋转2rads即可获得图像。 If you do this assignment at the end of the paint method: 如果您在paint方法的末尾进行此分配:

            zombieIdentity = ZombiePowered; 

the next time you paint the image it will be rotate 2rads more. 下次绘制图像时,它将旋转2rads。 About the issues with the position, take a look at rotate javadoc: 关于职位的问题,看一下rotate javadoc:

Concatenates this transform with a transform that rotates coordinates around an anchor point. 将此变换与围绕锚点旋转坐标的变换连接在一起。 This operation is equivalent to translating the coordinates so that the anchor point is at the origin (S1), then rotating them about the new origin (S2), and finally translating so that the intermediate origin is restored to the coordinates of the original anchor point (S3). 此操作等效于平移坐标,使锚点位于原点(S1),然后将其绕新原点旋转(S2),最后平移,以便将中间原点恢复到原始锚点的坐标(S3)。

This operation is equivalent to the following sequence of calls: 此操作等效于以下调用序列:

  translate(anchorx, anchory); // S3: final translation rotate(theta); // S2: rotate around anchor translate(-anchorx, -anchory); // S1: translate anchor to origin 

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM