Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用像素填充形状->;Java2D中的颜色函数?_Java_Java 2d - Fatal编程技术网

如何使用像素填充形状->;Java2D中的颜色函数?

如何使用像素填充形状->;Java2D中的颜色函数?,java,java-2d,Java,Java 2d,我有几个s需要用颜色渐变填充。我有一个将像素位置与其颜色关联的函数,如下所示: (x,y) -> some RGBA color 我的问题是:Java API的哪个部分允许我使用这样的函数来填充我的区域? 我已经研究了Java2D中的渐变,但我认为它们太具体了,无法实现我想要的(它们不接受像我这样的函数) 我试图理解//的内容,但在我的脑海中它仍然非常模糊,我仍然不明白我想要的东西是否可以用颜色模型来表示。我的印象是,这个类的目的不是将像素位置与其颜色相关联,而是将颜色表示与另一个表示

我有几个s需要用颜色渐变填充。我有一个将像素位置与其颜色关联的函数,如下所示:

(x,y) -> some RGBA color
我的问题是:Java API的哪个部分允许我使用这样的函数来填充我的
区域?

  • 我已经研究了Java2D中的渐变,但我认为它们太具体了,无法实现我想要的(它们不接受像我这样的函数)
  • 我试图理解//的内容,但在我的脑海中它仍然非常模糊,我仍然不明白我想要的东西是否可以用
    颜色模型来表示。我的印象是,这个类的目的不是将像素位置与其颜色相关联,而是将颜色表示与另一个表示相关联,对吗
  • 我想到的唯一可行的选择是使用a,并在每个像素上使用函数值的
    setRGB()
    。但是,由于它是一个矩形,当超出
    区域的边界时,我必须生成透明像素,这可能不是性能方面的最佳方式无论如何,这是正确的方法吗?
我在这里遗漏了一些更合适的解决方案吗


注意:我不是在寻找解决方案的详细实现,我只是想朝着正确的方向走;-)

我很好奇,实施了评论中提到的方法:

一种解决方案是用所需的颜色完全填充BuffereImage,然后使用给定区域作为图形#setClip绘制此图像吗?(不确定此处的性能,但很可能优于手动测试…)

结果如下:

这个例子使用了一些“虚拟”类

这是一个随机填充的
缓冲区图像
,仅用于此测试。此功能在
paintComponent
方法中被传输到
buffereImage
。在一个“真实”的应用程序中,这可以也应该在其他地方完成,可能在某个构造函数中,因此只需执行一次,但这取决于如何使用它。但是,然后,使用
区域
作为
图形2d
的剪裁形状,仅绘制图像

这似乎是可行的,但我还没有做任何详细的性能测试

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class CustomFillingTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        ColorFunction colorFunction = new ColorFunction();
        Area area = createTestArea();

        CustomFillingPanel customFillingPanel = 
            new CustomFillingPanel(colorFunction, area);
        f.getContentPane().add(customFillingPanel, BorderLayout.CENTER);

        f.setSize(400,200);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static Area createTestArea()
    {
        Font font = new Font("Monospaced", Font.BOLD, 120);
        final FontRenderContext fontRenderContext = 
            new FontRenderContext(null, true, true);
        GlyphVector glyphVector = font.createGlyphVector(
            fontRenderContext, "Test");
        Shape shape = glyphVector.getOutline(0,0);
        AffineTransform at = AffineTransform.getTranslateInstance(40, 100);
        Area area = new Area(at.createTransformedShape(shape));
        return area;
    }




}



class ColorFunction
{
    private final BufferedImage bufferedImage;

    ColorFunction()
    {
        this.bufferedImage = createDummyImage(1000, 1000);
    }

    private static BufferedImage createDummyImage(int w, int h)
    {
        Random random = new Random(1);
        BufferedImage image = 
            new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics graphics = image.createGraphics();
        graphics.setColor(Color.BLACK);
        graphics.fillRect(0, 0, w, h);
        for (int i=0; i<1000; i++)
        {
            int r = random.nextInt(255);
            int g = random.nextInt(255);
            int b = random.nextInt(255);
            Color c = new Color(r,g,b);
            int x = random.nextInt(w);
            int y = random.nextInt(h);
            int n = random.nextInt(w/10);
            graphics.setColor(c);
            graphics.fillRect(x,y,n,n);
        }
        graphics.dispose();
        return image;
    }

    int getColor(int x, int y)
    {
        int w = bufferedImage.getWidth();
        int h = bufferedImage.getHeight();
        return bufferedImage.getRGB(x%w, y%h);
    }
}


class CustomFillingPanel extends JPanel
{
    private final ColorFunction colorFunction;
    private final Area area;

    CustomFillingPanel(ColorFunction colorFunction, Area area)
    {
        this.colorFunction = colorFunction;
        this.area = area;
    }

    private static void paintIntoImage(
        ColorFunction colorFunction, BufferedImage bufferedImage)
    {
        int w = bufferedImage.getWidth();
        int h = bufferedImage.getHeight();
        for (int y=0; y<h; y++)
        {
            for (int x=0; x<w; x++)
            {
                int rgb = colorFunction.getColor(x, y);
                bufferedImage.setRGB(x, y, rgb);
            }
        }
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Rectangle b = area.getBounds();
        BufferedImage bufferedImage = 
            new BufferedImage(b.width,  b.height, BufferedImage.TYPE_INT_ARGB);
        paintIntoImage(colorFunction, bufferedImage);

        g.setClip(area);
        g.drawImage(bufferedImage, b.x, b.y, null);

    }
}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Font;
导入java.awt.Graphics;
导入java.awt.Rectangle;
导入java.awt.Shape;
导入java.awt.font.FontRenderContext;
导入java.awt.font.GlyphVector;
导入java.awt.geom.AffineTransform;
导入java.awt.geom.Area;
导入java.awt.image.buffereImage;
导入java.util.Random;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
公共类CustomFillingTest
{
公共静态void main(字符串[]args)
{
SwingUtilities.invokeLater(新的Runnable()
{
@凌驾
公开募捐
{
createAndShowGUI();
}
});
}
私有静态void createAndShowGUI()
{
JFrame f=新的JFrame();
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ColorFunction ColorFunction=新的ColorFunction();
面积=createTestArea();
CustomFillingPanel CustomFillingPanel=
新定制填充面板(颜色功能、面积);
f、 getContentPane().add(customFillingPanel,BorderLayout.CENTER);
f、 设置大小(400200);
f、 setLocationRelativeTo(空);
f、 setVisible(真);
}
专用静态区域createTestArea()
{
Font Font=新字体(“等距”,Font.BOLD,120);
最终FontRenderContext FontRenderContext=
新建FontRenderContext(null、true、true);
GlyphVector GlyphVector=font.createGlyphVector(
fontRenderContext,“测试”);
Shape Shape=glyphVector.getOutline(0,0);
AffineTransform at=AffineTransform.getTranslateInstance(40100);
面积=新面积(位于createTransformedShape(形状));
返回区;
}
}
类着色函数
{
专用最终缓冲区映像缓冲区映像;
ColorFunction()
{
this.buffereImage=createDummyImage(10001000);
}
私有静态缓冲区映像createDummyImage(int w,int h)
{
随机数=新随机数(1);
BuffereImage图像=
新的BuffereImage(w,h,BuffereImage.TYPE_INT_ARGB);
Graphics Graphics=image.createGraphics();
图形.设置颜色(颜色.黑色);
图形.fillRect(0,0,w,h);

对于(int i=0;i我很好奇,并实施了评论中提到的方法:

一种解决方案是用所需的颜色完全填充BuffereImage,然后使用给定区域作为图形#setClip绘制此图像吗?(此处的性能不确定,但很可能比手动测试更好…)

结果如下:

这个例子使用了一些“虚拟”类

这是由一个随机填充的
BufferedImage
支持的,仅用于此测试。此函数在
paintComponent
方法中转换为
BufferedImage
。在“real”中在应用程序案例中,这可以也应该在其他地方完成,可能是在某些构造函数中,因此只需执行一次,但这取决于如何使用。然而,然后,仅使用
区域
作为
图形2d
的剪裁形状来绘制图像

这似乎是可行的,但我还没有做任何详细的性能测试

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class CustomFillingTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        ColorFunction colorFunction = new ColorFunction();
        Area area = createTestArea();

        CustomFillingPanel customFillingPanel = 
            new CustomFillingPanel(colorFunction, area);
        f.getContentPane().add(customFillingPanel, BorderLayout.CENTER);

        f.setSize(400,200);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static Area createTestArea()
    {
        Font font = new Font("Monospaced", Font.BOLD, 120);
        final FontRenderContext fontRenderContext = 
            new FontRenderContext(null, true, true);
        GlyphVector glyphVector = font.createGlyphVector(
            fontRenderContext, "Test");
        Shape shape = glyphVector.getOutline(0,0);
        AffineTransform at = AffineTransform.getTranslateInstance(40, 100);
        Area area = new Area(at.createTransformedShape(shape));
        return area;
    }




}



class ColorFunction
{
    private final BufferedImage bufferedImage;

    ColorFunction()
    {
        this.bufferedImage = createDummyImage(1000, 1000);
    }

    private static BufferedImage createDummyImage(int w, int h)
    {
        Random random = new Random(1);
        BufferedImage image = 
            new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics graphics = image.createGraphics();
        graphics.setColor(Color.BLACK);
        graphics.fillRect(0, 0, w, h);
        for (int i=0; i<1000; i++)
        {
            int r = random.nextInt(255);
            int g = random.nextInt(255);
            int b = random.nextInt(255);
            Color c = new Color(r,g,b);
            int x = random.nextInt(w);
            int y = random.nextInt(h);
            int n = random.nextInt(w/10);
            graphics.setColor(c);
            graphics.fillRect(x,y,n,n);
        }
        graphics.dispose();
        return image;
    }

    int getColor(int x, int y)
    {
        int w = bufferedImage.getWidth();
        int h = bufferedImage.getHeight();
        return bufferedImage.getRGB(x%w, y%h);
    }
}


class CustomFillingPanel extends JPanel
{
    private final ColorFunction colorFunction;
    private final Area area;

    CustomFillingPanel(ColorFunction colorFunction, Area area)
    {
        this.colorFunction = colorFunction;
        this.area = area;
    }

    private static void paintIntoImage(
        ColorFunction colorFunction, BufferedImage bufferedImage)
    {
        int w = bufferedImage.getWidth();
        int h = bufferedImage.getHeight();
        for (int y=0; y<h; y++)
        {
            for (int x=0; x<w; x++)
            {
                int rgb = colorFunction.getColor(x, y);
                bufferedImage.setRGB(x, y, rgb);
            }
        }
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Rectangle b = area.getBounds();
        BufferedImage bufferedImage = 
            new BufferedImage(b.width,  b.height, BufferedImage.TYPE_INT_ARGB);
        paintIntoImage(colorFunction, bufferedImage);

        g.setClip(area);
        g.drawImage(bufferedImage, b.x, b.y, null);

    }
}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Font;
导入java.awt.Graphics;
导入java.awt.Rectangle;
导入java.awt.Shape;
导入java.awt.font.FontRenderContext;
导入java.awt.font.GlyphVector;
导入java.awt.geom.AffineTransform;
进口