Cutting part of an image out and keeping the original image

感情迁移 提交于 2019-12-25 18:32:24

问题


So I have a black image that acts as darkness (In my game). I want to show a small portion around the character only. Like so

The red square is the player. The green bit is the ground in the game (grass). The black is the shadow/darkness.

What I want to do is cut a Ellipse/hole out of the blank, black image. I want this Ellipse to be centered around the players (The red square) x and y position.

Currently I am using this to get the effect:

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

But, this processes extremely slow and laggs the players movement drastically.

Is this possible?


回答1:


..the Player is the red square. Basically what i want to do is cut a circle out of the blank, black image around the coordinates of the player relative to said black image.

What DYM by 'black image' - exactly? To me that just looks like the BG is painted black, which would make more sense for any solid color. In that case, just create the red thing using an Area, fill it, then for the border set a stroke & the color to black, and draw it. This example shows how.

The relevant part of that short code is..

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

I must be bored. This is an animated SSCCE version of the code that drew the image above. It is typically showing >130 FPS. And that is on a clunky machine for which I told the guy my spec. was 'cheap' & reminded him twice that I don't play (heavy rendering) games.

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


来源:https://stackoverflow.com/questions/11117126/cutting-part-of-an-image-out-and-keeping-the-original-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!