使用鼠标将像素绘制到BufferedImage - 提高性能

时间:2015-05-04 20:54:17

标签: java drawing mouse bufferedimage pixels

我从Processing中的编程切换到Java,现在,我正在尝试将一些技术转换为纯Java编程语言。 似乎我的代码有时会滞后,它也比我的Processing草图慢。我弄错了吗?我怎么能改进我的代码?这种计算是否也适用于gpu计算,可能在lwjgl?

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.Canvas;
import java.awt.Graphics;
import java.util.Random;

import javax.swing.JFrame;

public class Main extends Canvas implements Runnable {

    public static final int WIDTH = 1280;
    public static final int HEIGHT = 800;

    private int xstart;
    private int ystart;
    private int xend;
    private int yend;

    private int xPos;
    private int yPos;

    private Thread thread;
    private boolean isRunning = false;
    private BufferedImage img;
    private int[] pixels;

    private Random r;

    public Main() {
        img = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

        pixels = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
        r = new Random();

        xPos = WIDTH / 2;
        yPos = HEIGHT / 2;

        xstart = xPos - 200;
        ystart = yPos - 200;
        xend = xPos + 200;
        yend = yPos + 200;
    }

    @Override
    public void run() {
        while (isRunning) {
            render();
        }
    }

    private void start() {
        if (isRunning)
            return;
        isRunning = true;
        thread = new Thread(this);
        thread.start();
    }

    private void stop() {
        if (!isRunning)
            return;
        isRunning = false;
        try {
            thread.join();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
    }

    private void render() {
        addMouseMotionListener(new MouseMotionListener() {
            public void mouseDragged(MouseEvent e) {
                xPos = e.getX();
                yPos = e.getY();
            }

            public void mouseMoved(MouseEvent e) {
            }
        });

        addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e) {
                xPos = e.getX();
                yPos = e.getY();

            }

            public void mousePressed(MouseEvent e) {
                xPos = e.getX();
                yPos = e.getY();

            }

            public void mouseReleased(MouseEvent e) {
                xPos = e.getX();
                yPos = e.getY();
            }

            public void mouseEntered(MouseEvent e) {
            }

            public void mouseExited(MouseEvent e) {
            }
        });
        xstart = xPos - 50;
        ystart = yPos - 50;
        xend = xPos + 50;
        yend = yPos + 50;

        if (xstart < 0)
            xstart = 0;
        if (xstart > WIDTH)
            xstart = WIDTH;
        if (ystart < 0)
            ystart = 0;
        if (ystart > HEIGHT)
            ystart = HEIGHT;
        if (xend < 0)
            xend = 0;
        if (xend > WIDTH)
            xend = WIDTH;
        if (yend < 0)
            yend = 0;
        if (yend > HEIGHT)
            yend = HEIGHT;

        BufferStrategy bs = this.getBufferStrategy();
        if (bs == null) {
            createBufferStrategy(3);
            return;
        }

        for (int i = 0; i < WIDTH * HEIGHT; i++) {
            pixels[i] *= 0.99;
            if (pixels[i] <= 0)
                pixels[i] = 0;
        }

        for (int y = ystart; y < yend; y++) {
            for (int x = xstart; x < xend; x++) {
                int i = x + y * WIDTH;
                pixels[i] = r.nextInt(0xffffff);
            }
        }

        Graphics g = bs.getDrawGraphics();
        g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
        g.dispose();
        bs.show();
    }

    public static void main(String[] args) {
        Main main = new Main();
        JFrame frame = new JFrame();
        frame.add(main);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH, HEIGHT);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true);
        main.start();
    }
}

1 个答案:

答案 0 :(得分:0)

每次调用渲染时你都会添加新的MouseListeners,这意味着,每次发生MouseEvent时,他们都必须通知并且不断增加侦听器列表,所有这些似乎都是同样的事情......

相反,请在构造函数中设置侦听器

我还建议摆脱&#34;渲染线程&#34;只需在屏幕更新时使用渲染方法(使用被动绘画而不是主动渲染)