当前位置: 首页 > 知识库问答 >
问题:

Java2D Alpha映射图像

白飞飙
2023-03-14

使用Graphics2D,我如何拍摄黑白图像,并使用它定义应该在另一个图像上渲染什么和不应该在另一个图像上渲染什么?

E、 g如果我有一个图像,比如说,一个字段,在该字段上是一头奶牛,在另一个相同尺寸的图像上,我在黑色背景上,在奶牛的相同坐标处绘制一个白色框,当用Java渲染时,除了我有白色框的奶牛之外,图像将全部为黑色?

共有1个答案

舒斯伯
2023-03-14

编辑:根据聊天中的长时间讨论,很明显对意图存在误解,最初的问题是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();
    }
}

(迟)在评论中编辑请求:

要添加另一个阴影(无论现有的灯光如何),可以创建一个draShadow方法,在绘制灯光后重新应用阴影。它基本上使用另一个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 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();
    }
}
 类似资料:
  • 问题内容: 使用Graphics2D,我如何拍摄黑白图像,并用来定义 在另一幅图像上应该渲染和不应该渲染的图像? 例如,如果我有一个图像,例如一个字段,并且在该字段上是一头 母牛,那么在用Java渲染时 , 在相同尺寸的另一幅图像上,我会在黑色背景上以与母牛相同的坐标绘制一个白框图像会是 全黑的,除了我有白盒子的那头牛? 问题答案: 编辑:基于聊天中的长时间讨论,很明显有人 对意图有误解,而最初的

  • 问题内容: 使用Graphics2D,我如何拍摄黑白图像,并用来定义 在另一幅图像上应该渲染和不应该渲染的图像? 例如,如果我有一个图像,例如一个字段,并且在该字段上是一头 母牛,那么在用Java渲染时 , 在相同尺寸的另一幅图像上,我会在黑色背景上以与母牛相同的坐标绘制一个白框图像会是 全黑的,除了我有白盒子的那头牛? 问题答案: 编辑:基于聊天中的长时间讨论,很明显有人 对意图有误解,而最初的

  • 您可以使用JavaScript创建客户端图像映射。 客户端图像映射由《img /》标记的usemap属性启用,并由特殊的“map”和《area》扩展标记定义。 将使用表格将要形成地图的图像插入到页面中 元素正常,除了它带有一个名为usemap的额外属性。 usemap属性的值是“map”元素上name属性的值,您将要遇到它,前面有井号或井号。 元素实际上为图像创建了地图,通常紧跟在元素之后。它充当

  • 问题内容: 如何在不使用Hibernate类的情况下在JPA中映射Map? 问题答案: 以下内容对您没有帮助吗? 可以是任何实体类型,包括。

  • 关于切片 网页可以包含许多元素 - HTML 文本、位图图像和矢量图等等。在 Illustrator 中,可以使用切片来定义图稿中不同 Web 元素的边界。例如,如果图稿包含需要以 JPEG 格式进行优化的位图图像,而图像其他部分更适合作为 GIF 文件进行优化,则可以使用切片隔离位图图像。使用 “存储为 Web 和设备所用格式 ”命令将图稿存储为网页时,您可以选择将每个切片存储为一个独立文件,它

  • 在OpenCV中,可以使用类的方法将不同的颜色贴图应用于图像。以下是这种方法的语法 - 该方法接受以下参数 - src - 表示此操作的源(输入图像)的对象。 dst - 表示此操作的目标(输出图像)的对象。 colormap - 表示要应用的颜色映射的类型的整数类型变量。 示例 以下程序演示了如何将彩色映射应用于图像。 假定以下是上述程序中指定的输入图像:。 执行上面示例代码,得到以下结果 -