我需要一个面板,在其中可以进行绘制。我希望能够逐像素绘制。
注:我不需要线条/圆等其他图形。 提示:图形库并不重要,可以是awt、swing、qt等任何一个库。我只想拥有通常由Bufferedimage或类似的东西表示的东西,在其中设置单个像素的颜色,然后将其渲染到屏幕上。
一种实现方式的示例:
// Create the new image needed
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB );
for ( int rc = 0; rc < height; rc++ ) {
for ( int cc = 0; cc < width; cc++ ) {
// Set the pixel colour of the image n.b. x = cc, y = rc
img.setRGB(cc, rc, Color.BLACK.getRGB() );
}//for cols
}//for rows
然后从重写的paintComponent(Graphics g)方法内部进行操作
((Graphics2D)g).drawImage(img, <args>)
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Set the colour of pixel (x=1, y=2) to black
g.setColor(Color.BLACK);
g.drawLine(1, 2, 1, 2);
}
我曾使用过这种技术,速度并不是很慢。我没有与使用BufferedImage对象进行比较。
对于此问题,我建议使用BufferedImage
,它可以显示......或者你可以设置单个像素的颜色,然后将其渲染到屏幕上。
在JLabel
中显示-如此答案所示。
当然,一旦我们有了BufferedImage
的实例,我们就可以使用setRGB(..)
方法。
fun drawLand(area: Rectangle): BufferedImage {
val height = area.height
val image = BufferedImage(area.width, height, BufferedImage.TYPE_INT_ARGB)
val g2 = image.createGraphics()
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY)
g2.background = Color.PINK
g2.clearRect(area.x, area.y, area.width, area.height)
val squares: Sequence<Square> = repo.getSquares(area)
val pixels: IntArray = (image.raster.dataBuffer as DataBufferInt).data
for (square in squares) {
val color = square.color or OPAQUE // 0xFF000000.toInt()
val base = square.location.y * height + square.location.x
pixels[base] = color
}
g2.dispose()
return image
}
说明:
在背景中,图像由一些Java原始类型的数组支持,具体取决于BufferedImage.TYPE_
。
这里我选择了TYPE_INT_ARGB
,因此每个像素都方便地是一个Int
。然后你可以逐行处理底层像素。
Screen
类来实现:public class Screen {
private int width, height;
public int[] pixels;
public Screen(int width, int height) {
this.width = width;
this.height = height;
pixels = new int[width * height];
}
public void render() {
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
pixels[x + y * width] = 0xFFFFFF; //make every pixel white
}
}
}
public void clear() {
for(int i = 0; i < pixels.length; i++) {
pixels[i] = 0; //make every pixel black
}
}
}
然后在你的主类中:
private Screen screen;
private BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
screen.clear();
screen.render();
for(int i = 0; i < pixels.length; i++) {
pixels[i] = screen.pixels[i];
}
Graphics g = bs.getDrawGraphics();
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.dispose();
bs.show();
}
应该可以,我想。
drawLine
并使用相同的起始点和结束点。 - Extreme Coders