简体   繁体   中英

Java BufferedImage: How do i copy an image properly n times by accessing the pixel - array?

I am dealing with a problem which kind of "forked" from a project I'm working on. It was not necessary solving for the project itself, but I'm mentioning the origin because it is kind of a 'strangely specific' task.

I am trying to read in a small BufferedImage from a file (8x8 pixels). This image's pixels are written into an integer array, with length 64 (obviously).

Then, a new Array with the length 64*64 (=4096) is created. The pixels of the small array are copied into the large one 64 times, just resetting the smaller index to 0 everytime it reaches the end.

Finally, I create a new BufferedImage with width = 64 and height = 64. The large array is then set as rgbArray of said BufferedImage. The code is as follows:

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, 0, 64, 64);

    int[] smallPixels = new int[64];

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

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

    copiedNTimes.setRGB(0, 0, 64, 64, copied, 0, 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;
}

It works more or less as I expected it to, but images are written 'shifted':

smallStripes.png:

在此处输入图片说明

result.png :

在此处输入图片说明

My question is:

How could I accomplish that the stripes 'line up' to each other? Right now it is, from left to right, 8px black, 8px white, 8px black... and so forth. Why not 64 px black (new line) 64 px white (new line) etc.?

As is already said, it is oddly specific and oversimplified so I can describe it better.

The code you have uses scanline=8 as last parameter to setRGB and also wrong logic in copyNTimes which causes your stripped effect. If you want 8x8 pixel image repeating into 64x64 pixel image as 8x8 blocks either replace your setRGB call with this to repeat the small image into the larger one:

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

Or replace your setRGB call with this to build the larger int[] first and apply it in one step:

copiedNTimes.setRGB(0, 0, 64, 64, copied, 0, 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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM