Java2D Alpha Mapping图像(Java2D Alpha Mapping images)

编程入门 行业动态 更新时间:2024-10-28 13:21:55
Java2D Alpha Mapping图像(Java2D Alpha Mapping images)

使用Graphics2D,我如何拍摄黑白图像,并用于定义应该和不应该在另一张图像上呈现的内容?

例如,如果我有一个说的图像,一个字段,并且在该字段上是一头牛,并且在另一个相同尺寸的图像上,我在黑色背景上绘制一个白色框,在牛的相同坐标处,当用Java渲染时除了我有白色盒子的母牛外,图像全是黑色的吗?

Using Graphics2D, how can I take a black and white image, and use to define what should and what shouldn't rendered on another image?

E.g if I had an image of say, a field, and on that field is a cow, and on another image of the same dimensions I draw a white box on a black background, at the same coordinates of the cow, when rendered in Java the image would be all black, apart from the cow where I had the white box?

最满意答案

编辑:基于聊天中的长时间讨论,很明显有关于意图的误解,原始问题遭受了XY问题 :如何使用掩蔽图像构成图像的问题只有一个解决 实际问题的方法 - 即在瓷砖地图上绘制一些阴影/灯光效果。 该帖子的原始版本可以在修订历史中看到。

实际目标显然是在图像上添加“光效”。 以下是如何实现这一目标的示例:

原始图像在背景中绘制 在图像上绘制“阴影图像”。

“阴影图像”最初几乎是一种近乎黑色的图像。 使用RadialGradientPaint将灯光绘制到此图像中。 选择这种颜色的颜色,这样它们可以使阴影图像在光线所在的位置不那么不透明,而不是黑色。 这导致这些区域出现点亮,而其他部分仍然是黑暗的。

import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.MultipleGradientPaint.CycleMethod; import java.awt.Point; import java.awt.RadialGradientPaint; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class LightEffectTest2 { public static void main(String args[]) { SwingUtilities.invokeLater(new Runnable() { public void run() { new LightEffectTest2(); } }); } public LightEffectTest2() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.getContentPane().add(new LightEffectPanel2()); f.setSize(600,600); f.setVisible(true); } } class LightEffectPanel2 extends JPanel implements MouseMotionListener { private Point point = new Point(0,0); private BufferedImage image; private BufferedImage shadow; public LightEffectPanel2() { image = createExampleImage(600,600); shadow = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); addMouseMotionListener(this); } private static BufferedImage createExampleImage(int w, int h) { BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics g = image.getGraphics(); Random random = new Random(0); for (int i=0; i<200; i++) { int x = random.nextInt(w); int y = random.nextInt(h); Color c = new Color( random.nextInt(255), random.nextInt(255), random.nextInt(255)); g.setColor(c); g.fillOval(x-20, y-20, 40, 40); } g.dispose(); return image; } @Override protected void paintComponent(Graphics gr) { super.paintComponent(gr); Graphics2D g = (Graphics2D)gr; g.drawImage(image, 0,0,null); drawLights(); g.drawImage(shadow, 0,0, null); } private void drawLights() { Graphics2D g = shadow.createGraphics(); g.setComposite(AlphaComposite.Src); g.setColor(new Color(0,0,16,240)); g.fillRect(0,0,getWidth(),getHeight()); drawLight(g, new Point(100,100)); drawLight(g, point); g.dispose(); } private void drawLight(Graphics2D g, Point pt) { float radius = 100; g.setComposite(AlphaComposite.DstOut); Point2D center = new Point2D.Float(pt.x, pt.y); float[] dist = {0.0f, 1.0f}; Color[] colors = {new Color(255,255,255,255), new Color(0,0,0,0) }; RadialGradientPaint p = new RadialGradientPaint( center, radius, dist, colors, CycleMethod.NO_CYCLE); g.setPaint(p); g.fillOval(pt.x-(int)radius,pt.y-(int)radius,(int)radius*2,(int)radius*2); } @Override public void mouseDragged(MouseEvent e) { } @Override public void mouseMoved(MouseEvent e) { point = e.getPoint(); repaint(); } }

(已故)编辑对于评论中的请求:

要添加另一个阴影 (无论现有灯光如何),可以创建一个drawShadow方法,在绘制灯光后重新应用阴影。 它基本上使用另一个RadialGradientPaint,它部分“恢复”原始的,暗色的暗影图像。

LightEffectTest3

(阴影在这里给出了一个更锐利的边框,以使效果更加明显)

import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.MultipleGradientPaint.CycleMethod; import java.awt.Point; import java.awt.RadialGradientPaint; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class LightEffectTest3 { public static void main(String args[]) { SwingUtilities.invokeLater(new Runnable() { public void run() { new LightEffectTest3(); } }); } public LightEffectTest3() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.getContentPane().add(new LightEffectPanel3()); f.setSize(600,600); f.setVisible(true); } } class LightEffectPanel3 extends JPanel implements MouseMotionListener { private Point point = new Point(0,0); private BufferedImage image; private BufferedImage shadow; public LightEffectPanel3() { image = createExampleImage(600,600); shadow = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); addMouseMotionListener(this); } private static BufferedImage createExampleImage(int w, int h) { BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics g = image.getGraphics(); Random random = new Random(0); for (int i=0; i<200; i++) { int x = random.nextInt(w); int y = random.nextInt(h); Color c = new Color( random.nextInt(255), random.nextInt(255), random.nextInt(255)); g.setColor(c); g.fillOval(x-20, y-20, 40, 40); } g.dispose(); return image; } @Override protected void paintComponent(Graphics gr) { super.paintComponent(gr); Graphics2D g = (Graphics2D)gr; g.drawImage(image, 0,0,null); drawLights(); g.drawImage(shadow, 0,0, null); } private void drawLights() { Graphics2D g = shadow.createGraphics(); g.setComposite(AlphaComposite.Src); g.setColor(new Color(0,0,16,240)); g.fillRect(0,0,getWidth(),getHeight()); drawLight(g, new Point(200,200)); drawLight(g, point); drawShadow(g, new Point(250,250)); g.dispose(); } private void drawLight(Graphics2D g, Point pt) { float radius = 150; g.setComposite(AlphaComposite.DstOut); Point2D center = new Point2D.Float(pt.x, pt.y); float[] dist = {0.0f, 1.0f}; Color[] colors = {new Color(255,255,255,255), new Color(0,0,0,0) }; RadialGradientPaint p = new RadialGradientPaint( center, radius, dist, colors, CycleMethod.NO_CYCLE); g.setPaint(p); g.fillOval(pt.x-(int)radius,pt.y-(int)radius, (int)radius*2,(int)radius*2); } private void drawShadow(Graphics2D g, Point pt) { float radius = 75; g.setComposite(AlphaComposite.DstOver); Point2D center = new Point2D.Float(pt.x, pt.y); float[] dist = {0.0f, 0.7f, 1.0f}; Color[] colors = { new Color(0,0,0,200), new Color(0,0,0,150), new Color(255,255,255,0) }; RadialGradientPaint p = new RadialGradientPaint( center, radius, dist, colors, CycleMethod.NO_CYCLE); g.setPaint(p); g.fillOval(pt.x-(int)radius,pt.y-(int)radius, (int)radius*2,(int)radius*2); } @Override public void mouseDragged(MouseEvent e) { } @Override public void mouseMoved(MouseEvent e) { point = e.getPoint(); repaint(); } }

EDIT: Based on a long discussion in the chat, it became clear that there was a misunderstanding about the intention, and the original question suffered from the XY-Problem: The question of how to compose an image with a masking image was only about one solution attempt for the actual problem - namely painting some shadow/light effects on a tile map. The original versions of the post can be seen in the revision history.

The actual goal was obviously to add a "light effect" over the image. Here is an example of how this can be achieved:

The original image is painted in the background A "shadow image" is painted over the image.

The "shadow image" is initially a nearly opaqe, nearly black image. The lights are painted into this image, with a RadialGradientPaint. The colors for this paint are chosen so that they make the shadow image less opaque and less black at the places where the lights should be. This causes these areas to appear lighted, while the other parts remain dark.

import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.MultipleGradientPaint.CycleMethod; import java.awt.Point; import java.awt.RadialGradientPaint; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class LightEffectTest2 { public static void main(String args[]) { SwingUtilities.invokeLater(new Runnable() { public void run() { new LightEffectTest2(); } }); } public LightEffectTest2() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.getContentPane().add(new LightEffectPanel2()); f.setSize(600,600); f.setVisible(true); } } class LightEffectPanel2 extends JPanel implements MouseMotionListener { private Point point = new Point(0,0); private BufferedImage image; private BufferedImage shadow; public LightEffectPanel2() { image = createExampleImage(600,600); shadow = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); addMouseMotionListener(this); } private static BufferedImage createExampleImage(int w, int h) { BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics g = image.getGraphics(); Random random = new Random(0); for (int i=0; i<200; i++) { int x = random.nextInt(w); int y = random.nextInt(h); Color c = new Color( random.nextInt(255), random.nextInt(255), random.nextInt(255)); g.setColor(c); g.fillOval(x-20, y-20, 40, 40); } g.dispose(); return image; } @Override protected void paintComponent(Graphics gr) { super.paintComponent(gr); Graphics2D g = (Graphics2D)gr; g.drawImage(image, 0,0,null); drawLights(); g.drawImage(shadow, 0,0, null); } private void drawLights() { Graphics2D g = shadow.createGraphics(); g.setComposite(AlphaComposite.Src); g.setColor(new Color(0,0,16,240)); g.fillRect(0,0,getWidth(),getHeight()); drawLight(g, new Point(100,100)); drawLight(g, point); g.dispose(); } private void drawLight(Graphics2D g, Point pt) { float radius = 100; g.setComposite(AlphaComposite.DstOut); Point2D center = new Point2D.Float(pt.x, pt.y); float[] dist = {0.0f, 1.0f}; Color[] colors = {new Color(255,255,255,255), new Color(0,0,0,0) }; RadialGradientPaint p = new RadialGradientPaint( center, radius, dist, colors, CycleMethod.NO_CYCLE); g.setPaint(p); g.fillOval(pt.x-(int)radius,pt.y-(int)radius,(int)radius*2,(int)radius*2); } @Override public void mouseDragged(MouseEvent e) { } @Override public void mouseMoved(MouseEvent e) { point = e.getPoint(); repaint(); } }

(late) EDIT For the request in the comments:

To add another shadow (regardless of the existing lights), one can create a drawShadow method that re-applies the shadows after the lights have been drawn. It basically uses another RadialGradientPaint that partially "restores" the original, opaqe, dark shadow image.

LightEffectTest3

(The shadow is given a somewhat sharper border here, to make the effect more visible)

import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.MultipleGradientPaint.CycleMethod; import java.awt.Point; import java.awt.RadialGradientPaint; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class LightEffectTest3 { public static void main(String args[]) { SwingUtilities.invokeLater(new Runnable() { public void run() { new LightEffectTest3(); } }); } public LightEffectTest3() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.getContentPane().add(new LightEffectPanel3()); f.setSize(600,600); f.setVisible(true); } } class LightEffectPanel3 extends JPanel implements MouseMotionListener { private Point point = new Point(0,0); private BufferedImage image; private BufferedImage shadow; public LightEffectPanel3() { image = createExampleImage(600,600); shadow = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); addMouseMotionListener(this); } private static BufferedImage createExampleImage(int w, int h) { BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics g = image.getGraphics(); Random random = new Random(0); for (int i=0; i<200; i++) { int x = random.nextInt(w); int y = random.nextInt(h); Color c = new Color( random.nextInt(255), random.nextInt(255), random.nextInt(255)); g.setColor(c); g.fillOval(x-20, y-20, 40, 40); } g.dispose(); return image; } @Override protected void paintComponent(Graphics gr) { super.paintComponent(gr); Graphics2D g = (Graphics2D)gr; g.drawImage(image, 0,0,null); drawLights(); g.drawImage(shadow, 0,0, null); } private void drawLights() { Graphics2D g = shadow.createGraphics(); g.setComposite(AlphaComposite.Src); g.setColor(new Color(0,0,16,240)); g.fillRect(0,0,getWidth(),getHeight()); drawLight(g, new Point(200,200)); drawLight(g, point); drawShadow(g, new Point(250,250)); g.dispose(); } private void drawLight(Graphics2D g, Point pt) { float radius = 150; g.setComposite(AlphaComposite.DstOut); Point2D center = new Point2D.Float(pt.x, pt.y); float[] dist = {0.0f, 1.0f}; Color[] colors = {new Color(255,255,255,255), new Color(0,0,0,0) }; RadialGradientPaint p = new RadialGradientPaint( center, radius, dist, colors, CycleMethod.NO_CYCLE); g.setPaint(p); g.fillOval(pt.x-(int)radius,pt.y-(int)radius, (int)radius*2,(int)radius*2); } private void drawShadow(Graphics2D g, Point pt) { float radius = 75; g.setComposite(AlphaComposite.DstOver); Point2D center = new Point2D.Float(pt.x, pt.y); float[] dist = {0.0f, 0.7f, 1.0f}; Color[] colors = { new Color(0,0,0,200), new Color(0,0,0,150), new Color(255,255,255,0) }; RadialGradientPaint p = new RadialGradientPaint( center, radius, dist, colors, CycleMethod.NO_CYCLE); g.setPaint(p); g.fillOval(pt.x-(int)radius,pt.y-(int)radius, (int)radius*2,(int)radius*2); } @Override public void mouseDragged(MouseEvent e) { } @Override public void mouseMoved(MouseEvent e) { point = e.getPoint(); repaint(); } }

更多推荐

本文发布于:2023-07-14 13:43:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1104807.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:图像   Alpha   Java2D   images   Mapping

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!