编程语言
首页 > 编程语言> > 通过线程缩放图像 – JAVA

通过线程缩放图像 – JAVA

作者:互联网

假设我有一张图片.我将图像放在JPanel中,并在JFrame中添加JPanel.图像从框架的底部移动到框架的顶部,同时使用AffineTransform减小其尺寸.变量使用线程更改.

所以这是以下代码:

public class SplashScreen extends JFrame{
    Image img1;
    int w=1,h=1;
    int x=0,y=0;
    Thread th = new Thread(new Runnable() {
    @Override
    public void run() {
        while(true){
            w-=0.05;
            h-=0.05;
            y-=2;
            x+=1;

            if(y==-100){
                new MainMenu_BlueJay().setVisible(true);
                dispose();
            }

            repaint();
            try {
                Thread.sleep(10);
            } catch (InterruptedException ex) {
                Logger.getLogger(SplashScreen.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
    }
});

JPanel p = new JPanel();

public SplashScreen(){
    setLayout(new BorderLayout());

    p.setPreferredSize(new Dimension(900,600));
    p.setBackground(Color.black);
    p.setLayout(new GridLayout());

    add(p);
    setTitle("BlueJay");
    setSize(900,600);

    getContentPane().setBackground(Color.black);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    setVisible(true);
    th.start();
    requestFocus();
    setFocusable(true);
}

@Override
public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g;

    img1 = new ImageIcon("images/Intro/BJ Production 2013.png").getImage();
    AffineTransform at = new AffineTransform();
    at.scale(w,h);
    g2d.setTransform(at);
    g2d.drawImage(img1, x, y, p);
}

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

但是我从上面的代码得到的只是黑屏.怎么了?无论如何,如果我不使用AffineTransform功能(只是从下往上移动),图像会显示并移动但框架会快速闪烁(闪烁).

有任何想法解决这个问题所以我可以移动图像,同时减小其大小,并解决闪烁/快速闪烁帧?

解决方法:

您不应该覆盖JFrame的paint方法.如果你想绘制任何东西,你应该在扩展JPanel的类中绘制它,在那里覆盖paintComponent方法.

您不应该在绘画方法中加载图像.这非常低效.您应该只在ONCE中加载图像,可能在构造函数中.

你不应该调用Graphics2D #setTransform().看一下http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics2D.html#setTransform%28java.awt.geom.AffineTransform%29的JavaDoc,它明确指出

警告:永远不应该使用此方法在现有变换之上应用新的坐标变换

你应该考虑你的w和h值.它们应该是绘制图像的大小,还是用作图像的缩放因子?将它们设置为AffineTransform的缩放因子将不具有将图像缩放到所需大小的效果.目前,它们被声明为int值,所以像w- = 0.05这样的东西无论如何都没有意义.

您应该清楚地了解如何描述图像应该执行的动画.

人们可以总结一下:

你不应该编写代码并假设它是“正确的”只是因为没有编译错误;-)

但是,以下代码段可能是迈向目标的第一步:

package stackoverflow;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SplashScreen extends JFrame
{
    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new SplashScreen();
            }
        });
    }    

    private PaintPanel paintPanel;

    public SplashScreen()
    {
        setTitle("BlueJay");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        getContentPane().setBackground(Color.BLACK);
        getContentPane().setLayout(new BorderLayout());

        paintPanel = new PaintPanel();
        getContentPane().add(paintPanel, BorderLayout.CENTER);

        setSize(900,600);
        setLocationRelativeTo(null);
        setFocusable(true);
        requestFocus();
        setVisible(true);

        startAnimation();
    }

    void startAnimation()
    {
        Thread thread = new Thread(new Runnable()
        {
            int x = 100;
            int y = 100;
            int w = 0;
            int h = 0;

            @Override
            public void run()
            {
                try
                {
                    Thread.sleep(500);
                }
                catch (InterruptedException ex)
                {
                    Thread.currentThread().interrupt();
                    return;
                }

                while (true)
                {
                    if (y == 200)
                    {
                        // new MainMenu_BlueJay().setVisible(true);
                        dispose();
                    }

                    x += 2;
                    y += 1;
                    w += 1;
                    h += 1;
                    paintPanel.setImageCoordinates(x, y, w, h);

                    repaint();
                    try
                    {
                        Thread.sleep(10);
                    }
                    catch (InterruptedException ex)
                    {
                        Thread.currentThread().interrupt();
                        return;
                    }

                }
            }
        });
        thread.start();
    }
}


class PaintPanel extends JPanel
{
    private final Image image;
    private int imageX, imageY;
    private int imageW, imageH;

    PaintPanel()
    {
        image = new ImageIcon("Clipboard02.jpg").getImage();
        imageX = 0;
        imageY = 0;
        imageW = 0;
        imageH = 0;
    }

    void setImageCoordinates(int imageX, int imageY, int imageW, int imageH)
    {
        this.imageX = imageX;
        this.imageY = imageY;
        this.imageW = imageW;
        this.imageH = imageH;
        repaint();
    }

    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D) gr;

        float scalingX = (float) imageW / image.getWidth(null);
        float scalingY = (float) imageH / image.getHeight(null);
        g.scale(scalingX, scalingY);

        int ix = (int)(imageX / scalingX);
        int iy = (int)(imageY / scalingY);
        g.drawImage(image, ix, iy, null);
    }
}

标签:java,swing,paint,repaint,thread-sleep
来源: https://codeday.me/bug/20190624/1280356.html