剪出图像的一部分并保留原始图像 [英] Cutting part of an image out and keeping the original image
问题描述
红色方块是玩家。
绿色位是游戏中的地面(草地)。
黑色是阴影/黑暗。
我想要做的是从空白的黑色图像中剪下一个椭圆/孔。我希望这个Ellipse以玩家(红色方块)的x和y位置为中心。
目前我正在使用它来获得效果:
$ (int y = 0; y$ 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屋!