Java 将图形绘制到数组中

Java 将图形绘制到数组中,java,arrays,rendering,Java,Arrays,Rendering,假设我有给定的数组: int[] array = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 是否有一种方法可以将图形绘制到该阵列中?例如,假设我们有一种方法可以通过x和y坐标访问该数组中的数据,我们可以制作一种方法,根据2个坐标在该数组中放置一条线。代码如下所示: public void dr

假设我有给定的数组:

int[] array = {
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0
    };
是否有一种方法可以将图形绘制到该阵列中?例如,假设我们有一种方法可以通过x和y坐标访问该数组中的数据,我们可以制作一种方法,根据2个坐标在该数组中放置一条线。代码如下所示:

public void drawLine(int x1, int y1, int x2, int y2) {
    ...     
}
int[] array = {
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0
    };
并且会转移这样的东西:

public void drawLine(int x1, int y1, int x2, int y2) {
    ...     
}
int[] array = {
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0
    };
为此:

int[] array = {
        1, 0, 0, 0, 0,
        0, 1, 0, 0, 0,
        0, 0, 1, 0, 0,
        0, 0, 0, 1, 0,
        0, 0, 0, 0, 1
    };
您必须能够传入任何一组坐标,并在阵列中放置一条计算线。我将如何实现这一点

调用drawLine(1,0,3,4)将创建如下内容:

int[] array = {
    0, 1, 0, 0, 0,
    0, 0, 1, 0, 0,
    0, 0, 1, 0, 0,
    0, 0, 0, 1, 0,
    0, 0, 0, 1, 0
};
另外,如果你的情况允许,我可以指定任意数量的点,并将它们全部连接起来,然后填写吗?(不,我不想使用任何库)。

非常诡计多端的方法(不自己实现绘图逻辑)是使用BuffereImage和数组的尺寸,并在此基础上绘图。在绘制完所需的直线后,您将迭代BuffereImage的像素并检查绘制的像素

private static void drawToArray(int[][] array2d, int x1, int y1, int x2, int y2) {
    int width = array2d[0].length; // width is columns and columns are second
    int height = array2d.length; // height is rows and rows are first

    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2d = image.createGraphics();
    g2d.setBackground(Color.WHITE);
    g2d.fillRect(0, 0, width, height);  // paint background white
    g2d.setColor(Color.BLACK);
    BasicStroke bs = new BasicStroke(1); // set black brush to size 1 (1 pixel)
    g2d.setStroke(bs);

    g2d.drawLine(x1, y1, x2, y2); // paint line on image

    // fill array with values, check entire image
    for (int row = 0; row < height; row++) {
        for (int column = 0; column < width; column++) {
            int clr = image.getRGB(row,column); // get color of pixel at position
            if (clr == Color.WHITE.getRGB()) { // white is -1
                array2d[row][column] = 0;
            } else {
                array2d[row][column] = 1;
            }
        }
    }
    g2d.dispose();
    // returning array is not necesery I am editing the array2d variable passed in
}
本例假设数组是二维的,并且每行的长度相同。如果你想使用一维数组,你必须自己定义它的宽度和高度。也代替

array2d[row][column] = 0;
你会的

array1d[row*width + column] = 0;
编辑1:编辑我的答案,使之更一般

编辑2:考虑性能

我怀疑我能否改进drawLine方法,所以唯一需要改进的地方是转换为2d阵列。可以从图像中获取表示为整数值的像素数组,并将其转换为2d数组。我更新了DrawToArray方法,并将注释线保留在那里作为解释

private static void drawToArray(int[][] array2d, int x1, int y1, int x2, int y2) {
    int width = array2d[0].length; // width is columns and columns are second
    int height = array2d.length; // height is rows and rows are first

    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2d = image.createGraphics();   // default color of image is 0 no need to paint background, just draw with color diferent than 0
    //g2d.setColor(Color.WHITE);               // default brush color is different than 0, expicitly setting is unnecesery
    //BasicStroke bs = new BasicStroke(1);
    //g2d.setStroke(bs);                       // default is 1 pixel expicitly setting is unnecesery

    g2d.drawLine(x1, y1, x2, y2); // paint line on image

    int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
    for (int i = 0, row = 0, col = 0; i < pixels.length; i++) {
        array2d[row][col] = pixels[i] == 0 ? 0 : 1; // no performance difference vs if/else just readability
        //array2d[row][col] = pixels[i]; // if you write it like this you will be "painting" with '-1's instead of '1's and save one if/else
        col++;
        // if is more readable here no performance difference vs ternary
        if (col == width) {
            col = 0;
            row++;
        }
    }
    g2d.dispose();
}
private static void drawToArray(int[]]array2d、int-x1、int-y1、int-x2、int-y2){
int-width=array2d[0]。长度;//宽度为列,列为第二
int height=array2d.length;//高度是行,行是第一行
BuffereImage=新的BuffereImage(宽度、高度、BuffereImage.TYPE_INT_RGB);
Graphics2D g2d=image.createGraphics();//图像的默认颜色为0无需绘制背景,只需使用与0不同的颜色绘制即可
//g2d.setColor(Color.WHITE);//默认笔刷颜色不同于0,显然设置不必要
//基本行程bs=新的基本行程(1);
//g2d.setStroke(bs);//默认值为1像素,显然设置不必要
g2d.绘制线(x1,y1,x2,y2);//在图像上绘制线
int[]像素=((DataBufferInt)image.getRaster().getDataBuffer()).getData();
for(inti=0,row=0,col=0;i

提高性能的另一个地方是根本不将其转换为2d数组,而是像我前面提到的那样访问这些值。但是如果你想用数字1而不是默认的-1来“绘制”,你必须在像素数组中循环,以将-1替换为1。

对于绘制线条很有用。
drawinline(1,0,2,4)
的输入看起来如何?至少对我来说,没有通用的解决方案,因为不清楚任何一组坐标的结果会是什么样子。
y
坐标在一维数组中没有任何意义。你必须在代码的某个地方确定网格的宽度/高度,才能画线,因为您使用的是普通的1D数组。@Berger我想他指的是2d数组。我必须在一秒钟内多次运行这样的代码,性能如何?@Llewv我的示例是使用图形绘制线。我怀疑使用自定义代码是否能提高效率。我能做的唯一一件事就是转换成int数组。getRGB()可能很慢。要快速转换为int数组,请查看此。