当前位置: 首页 > 面试题库 >

Java2D Alpha映射图像

水渊
2023-03-14
问题内容

使用Graphics2D,我如何拍摄黑白图像,并用来定义
在另一幅图像上应该渲染和不应该渲染的图像?

例如,如果我有一个图像,例如一个字段,并且在该字段上是一头 母牛,那么在用Java渲染时

在相同尺寸的另一幅图像上,我会在黑色背景上以与母牛相同的坐标绘制一个白框图像会是
全黑的,除了我有白盒子的那头牛?


问题答案:

编辑:基于聊天中的长时间讨论,很明显有人
对意图有误解,而最初的问题
是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部分
“还原”原始不透明暗影图像的图像。

(此处阴影被赋予了较清晰的边框,以使效果更
明显)

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,我如何拍摄黑白图像,并使用它定义应该在另一个图像上渲染什么和不应该在另一个图像上渲染什么? E、 g如果我有一个图像,比如说,一个字段,在该字段上是一头奶牛,在另一个相同尺寸的图像上,我在黑色背景上,在奶牛的相同坐标处绘制一个白色框,当用Java渲染时,除了我有白色框的奶牛之外,图像将全部为黑色?

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

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

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

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