user6005857
user6005857

Reputation: 631

Treating a 1 dimensional array like a 2 dimensional array in C to rotate an image

I have a 1 dimensional array that contains R,G,B and padding data of an image. Padding is used to make the width of the image divisible by 4. The array looks like this (this is just a simple example, I want the code to work for images of any size):

char imageArray[MAX] = {R,G,B,R,G,B,R,G,B,0,0,0,
                        R,G,B,R,G,B,R,G,B,0,0,0,
                        R,G,B,R,G,B,R,G,B,0,0,0}

This is a 1 dimensional array but it represents an image so I need to find a way to treat it like a 2 dimensional array so that I can access the desired rows and columns of the image to apply edits to the image without having to convert it to a 2 dimensional array.

What I want to do is rotate this image right 90 degrees, left 90 degrees and 180 degrees.

What I have is the width, the height and the size of the array.

For the array above, the width is 3 pixels, which is 9 bytes + 3 padding bytes, so width is 12 bytes. The height is equal to the number of rows, which is 3. The size of the array is ((Width*3)+padding)*Height = ((3*3)+3)*3=36.

I made the following image in paint which explains what I am trying to achieve (assume that each colored square is 1 pixel):

enter image description here

From this image I can see that it is possible to come up with an algorithm to perform the rotations by shifting pixels to the right or left on each row but I am not able to come up with this algorithm for the general case. My program has to be able to rotate images of any size.

Is it possible to achieve this modifications of the array using just the pixel width (3), height (3), padding (3) and array size (36) information?

Here is some code I wrote to test if I can successfully access each part of the array using a nested loop but it does not work. This code is very simple and I am using it to quickly test is I can access all parts of the image.

for (i = 0; i < height; i++) { //height = 3 in this case
    for (j = 0; j < (width*3)+padding; j++) { //width = 3 and padding = 3 in this case
        if (imageArray[i*j] > 127) {
            imageArray[i*j] = 0;
        } else {
            imageArray[i*j] = 255;
        }
    }
}

But this code doesn't work. It produces a strange result and it doesn't access every element in the array.

The following code produces the desired output but only for images with no padding:

for (i = 0; i < arraySize; i++) { //array size is 36 in this case

    if (imageArray[i] > 127) {
        imageArray[i] = 0;
    } else {
        imageArray[i] = 255;
    }
}

How can I deal with padding in this case? What I am doing above is not working so everything gets shifted and the resulting image looks messed up. If there is no padding, everything is fine. Can I draw each "row" of the image and then add the padding pixels? I am not exactly sure how to do that. For example, can I do the following to deal with padding

for (i = 0; i < height; i++) { //height = 3 in this case
    for (j = 0; j < width*3+padding; j++) { //width = 3 and padding = 3 in this case
        if (imageArray[i*j] > 127) {
            imageArray[i*j] = 0;
        } else {
            imageArray[i*j] = 255;
        }
    }
    //adding padding pixels before editing the next row.
}

Upvotes: 1

Views: 264

Answers (2)

Hassen Dhia
Hassen Dhia

Reputation: 585

To access and 1-dim array of n element as it is 2-dim (say width and height) array you need to choose bounderies of width and height so that width*height = n . and this is and example of accessing element of 1-dim array as it is 2-dim :

type array[size];
type get_element(int x,int y)
{
   return array[y*width+x]; // jump y lines of length 'width' and get the x'th               //    element of the next line
}

examples : for array of size 10 you can choose 2-dim (2,5) or (5,2)
for array of size 18 you can choose 2-dim (9,2) or (2,9) or (3,6) or (6,3)

Upvotes: 1

MadPidgeon
MadPidgeon

Reputation: 245

You can treat an int a[n*m] array as an int a[n][m] array by changing a[i][j] into a[m*i+j]. Perhaps that's what you attempted when you wrote imageArray[i*j]?

Upvotes: 1

Related Questions