剪出图像的一部分并保留原始图像 [英] Cutting part of an image out and keeping the original image

查看:205
本文介绍了剪出图像的一部分并保留原始图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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





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



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

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

$ (int y = 0; y ; b
$ b

  y ++){
//绘制掩码
g.setColor(Color.black);
if(!nearPlayer(x,y)){
g.drawLine(x,y,x,y);
}
}
}

但是,这个过程非常缓慢并且滞后球员运动。



这可能吗?

解决方案


..玩家是红色的方块。基本上我想要做的是围绕玩家坐标相对于黑色图像的空白黑色图像切出一个圆圈。


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





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

  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。这是一个笨重的机器,我告诉这个人我的规格。是'便宜'&

  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);
最后Daisy daisyPainter =新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 fps.setText(FPS:+ counter);
counter = 0;
timeLast = timeNow;
}
}
};
定时器定时器=新的定时器(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;
点位置;

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;

面积面积=新面积(核心);
$ b $ // left petal
area.add(new Area(new Ellipse2D.Double(
pad,(size-petalWidth)/ 2,petalLength,petalWidth)));
//右花瓣
area.add(新区域(新的Ellipse2D.Double(
(size-petalLength-pad),(size-petalWidth)/ 2,petalLength,petalWidth))) ;
//顶部花瓣
area.add(新区域(新的Ellipse2D.Double(
(size-petalWidth)/ 2,pad,petalWidth,petalLength)));
//底部花瓣
area.add(新的区域(新的Ellipse2D.Double(
(size-petalWidth)/ 2,(size-petalLength-pad),petalWidth,petalLength))) ;

返回区域;
}
}


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?

解决方案

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

这篇关于剪出图像的一部分并保留原始图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆