gpt4 book ai didi

java - 如何在 Java 2D 中使用像素->颜色函数填充形状?

转载 作者:行者123 更新时间:2023-12-02 05:50:20 25 4
gpt4 key购买 nike

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

(x,y) -> some RGBA color

我的问题是:Java API 的哪一部分允许我使用这样的函数来填充我的 Area

  • 我研究过 Java 2D 中的渐变,但我认为它们太具体,无法实现我想要的(它们不接受像我这样的函数)。
  • 我试图理解Paint/Raster/ColorModel东西,但它在我的脑海中仍然非常模糊,我仍然不明白我想要的是否可以用 ColorModel 表示。我的印象是,此类的目的不是将像素位置与其颜色相关联,而是将颜色表示与另一种表示相关联,我的说法正确吗?
  • 我想到的唯一可行的选择是使用 BufferedImage ,并使用我的函数值对每个像素使用 setRGB() 。但是,由于它是一个矩形,当超出我的 Area 范围时,我必须生成透明像素,这可能不是关于性能的最佳方法。 无论如何,这是正确的方法吗?

我在这里缺少一些更合适的解决方案吗?

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

最佳答案

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

Could one solution be to simply fill a BufferedImage completely with the desired colors, and then paint this image using the given area as the Graphics#setClip? (Not sure about the performance here, but most likely better than manual tests...)

结果如下:

enter image description here

此示例使用一些“虚拟”类

class ColorFunction
{
int getColor(int x, int y)
{
...
}
}

由随机填充的 BufferedImage 支持,仅用于此测试。该函数在 paintComponent 方法中被传输到 BufferedImage 中。在“真实”应用程序案例中,这可以而且应该在其他地方完成,也许在某个构造函数中,因此只需完成一次,但这取决于如何使用它。但是,然后,使用 Area 作为 Graphics2D 的剪切形状来绘制图像。

看起来可行,但我还没有做过详细的性能测试。

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 - 如何在 Java 2D 中使用像素->颜色函数填充形状?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23598281/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com