切出部分图像并保留原始图像

时间:2012-06-20 10:00:37

标签: java image image-processing graphics

所以我有一个充满黑暗的黑色图像(在我的游戏中)。我只想在角色周围展示一小部分。像这样

enter image description here

红色方块是玩家。 绿色位是游戏中的基础(草)。 黑色是阴影/黑暗。

我想要做的是从空白的黑色图像中切出一个椭圆/孔。我希望这个Ellipse以玩家(红色方块)x和y位置为中心。

目前我正在使用它来获得效果:

        for(int x = 0; x < width; x++) {
            for(int y = 0; y < height; y++) {
                //draw mask
                g.setColor(Color.black);
                if(!nearPlayer(x, y)) {
                    g.drawLine(x, y, x, y);
                }
            }
        }

但是,这个过程非常缓慢,并严重拖延了球员的运动。

这可能吗?

1 个答案:

答案 0 :(得分:1)

  

..玩家是红色方块。基本上我想要做的是从播放器坐标周围的空白黑色图像中切出一个圆圈,相对于所述黑色图像。

“黑色图像”的DYM究竟是什么?对我来说,看起来BG看起来是黑色的,这对于任何纯色都会更有意义。在这种情况下,只需使用Area填充创建红色的东西,然后为边框设置一个笔画&amp;颜色为黑色,绘制This example显示了如何。

该短代码的相关部分是..

public void paintDaisyPart(Graphics2D g, Area daisyArea) {
    g.setClip(daisyArea);

    g.setColor(Color.YELLOW);
    g.fillRect(0, 0, 200, 200);

    g.setColor(Color.YELLOW.darker());
    g.setClip(null);
    g.setStroke(new BasicStroke(3));
    g.draw(daisyArea);
}

我一定很无聊。这是一个动画 SSCCE版本的代码,用于绘制上面的图像。它通常显示> 130 FPS。这是一个笨重的机器,我告诉那个人我的规格。是'廉价'&amp;两次提醒他我不玩(重渲染)游戏。

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class DaisyDisplay {

    DaisyDisplay() {
        JPanel gui = new JPanel(new BorderLayout(2,2));

        final BufferedImage daisy = new BufferedImage(
                200,200,BufferedImage.TYPE_INT_RGB);
        final JLabel daisyLabel = new JLabel(new ImageIcon(daisy));
        gui.add(daisyLabel,BorderLayout.CENTER);
        final Daisy daisyPainter = new Daisy();
        daisyPainter.setSize(200);
        final JLabel fps = new JLabel("FPS: ");
        gui.add(fps,BorderLayout.SOUTH);

        ActionListener animator = new ActionListener() {
            int counter = 0;
            long timeLast = 0;
            long timeNow = 0;
            public void actionPerformed(ActionEvent ae) {
                Graphics2D g = daisy.createGraphics();
                g.setColor(Color.GREEN.darker());
                g.fillRect(0, 0, 200, 200);

                daisyPainter.paint(g);

                g.dispose();
                daisyLabel.repaint();

                counter++;
                timeNow = System.currentTimeMillis();
                if (timeLast<timeNow-1000) {
                    fps.setText("FPS: " + counter);
                    counter = 0;
                    timeLast = timeNow;
                }
            }
        };
        Timer timer = new Timer(1,animator);
        timer.start();

        JOptionPane.showMessageDialog(null, gui);
        timer.stop();
    }

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

class Daisy {

    double size = 200;
    Point location;

    double offset = 0.0;

    public void paint(Graphics2D g) {
        Area daisyArea = getDaisyShape();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                RenderingHints.VALUE_ANTIALIAS_ON);

        offset += .02d;

        AffineTransform plain = g.getTransform();

        g.setTransform(AffineTransform.getRotateInstance(
                offset + (Math.PI*1/8),
                100,100));
        paintDaisyPart(g,daisyArea);

        g.setTransform(AffineTransform.getRotateInstance(
                offset + (Math.PI*3/8),
                100,100));
        paintDaisyPart(g,daisyArea);

        g.setTransform(AffineTransform.getRotateInstance(
                offset,
                100,100));
        paintDaisyPart(g,daisyArea);

        g.setTransform(AffineTransform.getRotateInstance(
                offset + (Math.PI*2/8),
                100,100));
        paintDaisyPart(g,daisyArea);

        g.setTransform(plain);
    }

    public void setLocation(Point location) {
        this.location = location;
    }

    public void paintDaisyPart(Graphics2D g, Area daisyArea) {
        g.setClip(daisyArea);

        g.setColor(Color.YELLOW);
        g.fillRect(0, 0, 200, 200);

        g.setColor(Color.YELLOW.darker());
        g.setClip(null);
        g.setStroke(new BasicStroke(3));
        g.draw(daisyArea);
    }

    public void setSize(double size) {
        this.size = size;
    }

    public Area getDaisyShape() {
        int diameter = (int)size*6/20;

        Ellipse2D.Double core = new Ellipse2D.Double(
                (size-diameter)/2,(size-diameter)/2,diameter,diameter);

        int pad = 10;
        int petalWidth = 50;
        int petalLength = 75;

        Area area = new Area(core);

        // left petal
        area.add(new Area(new Ellipse2D.Double(
                pad,(size-petalWidth)/2,petalLength,petalWidth)));
        // right petal
        area.add(new Area(new Ellipse2D.Double(
                (size-petalLength-pad),(size-petalWidth)/2,petalLength,petalWidth)));
        // top petal
        area.add(new Area(new Ellipse2D.Double(
                (size-petalWidth)/2,pad,petalWidth,petalLength)));
        // bottom petal
        area.add(new Area(new Ellipse2D.Double(
                (size-petalWidth)/2,(size-petalLength-pad),petalWidth,petalLength)));

        return area;
    }
}