Java BufferedImage:如何通过访问像素数组正确复制图像n次?

问题描述

我正在处理一个问题,该问题来自我正在处理的项目中的那种“分叉”。不一定要解决项目本身,但是我要提到起源,因为它是一项“奇怪的特定任务”。

我正在尝试从文件(8x8像素)中读取一个小的BufferedImage。 该图像的像素被写入一个整数数组,长度为64(显然)。

然后,创建一个新的数组,其长度为64 * 64(= 4096)。小数组的像素会被复制到大数组中,每次64次,只是每次到达终点时将小索引重置为0。

最后,我创建一个新的BufferedImage,宽度为64,高度为64。然后将大数组设置为该BufferedImage的rgbArray。代码如下:

public static void main(String[] args)throws IOException {
    
    BufferedImage tocopy = ImageIO.read(new File("smallStripes.png"));
    BufferedImage copiednTimes = new BufferedImage(64,64,BufferedImage.TYPE_BYTE_BINARY); 
    //copiednTimes is to be the resulting image

    Graphics2D g2d = (Graphics2D) copiednTimes.getGraphics();
    g2d.setColor(Color.WHITE);
    g2d.fillRect(0,64);

    int[] smallPixels = new int[64];

    tocopy.getRGB(0,8,smallPixels,8);
    //copy the rgb array of read image into the 64 - array

    int[] copied = copyNTimes(smallPixels,new int[64*64]);

    copiednTimes.setRGB(0,copied,8);
    //setting the rgb array of result image to the copied one

    FileOutputStream fos = new FileOutputStream(new File("result.png"));
    ImageIO.write(copiednTimes,"png",fos);
}

static int[] copyNTimes(int[] small,int[] big){

    //this method copies the small array into the larger one
    //until the larger one is 'filled up'

    int index = 0;

    for(int x = 0 ; x < big.length; x++){
        big[x] = small[index];
        index++;
        if(index == small.length)
            index = 0;
    }

    return big;
}

它或多或少像我预期的那样工作,但是图像被写为“移位”:

smallStripes.png:

enter image description here

result.png:

enter image description here

我的问题是:

我怎样才能使条纹彼此“对齐”?现在从左到右分别是8px黑色,8px白色,8px黑色...等等。 为什么不选择64 px黑色(新行),64 px白色(新行)等?

正如已经说过的那样,它是奇怪的且过于简化,所以我可以更好地描述它。

解决方法

您使用的代码使用scanline = 8作为setRGB的最后一个参数,并且在copyNTimes中使用了错误的逻辑,这会导致剥离效果。如果您希望将8x8像素的图像以8x8块的形式重复转换为64x64像素的图像,请用以下方法替换setRGB调用,以将小图像重复成较大的图像:

for (int x = 0 ; x < 64 ; x += 8)
    for (int y = 0 ; y < 64 ; y += 8)
        copiedNTimes.setRGB(x,y,8,smallPixels,8);

或以此替换您的setRGB调用,以首先构建较大的int []并一步一步应用:

copiedNTimes.setRGB(0,64,copied,64);

static int[] copyNTimes(int[] small,int[] big){
    for(int x = 0 ; x < big.length; x++){
        big[x] = small[8 * ((x / 64) % 8) + (x % 8)];
    }
    return big;
}