Harman
Harman

Reputation: 539

flip BMP image horizontal in c

My function is getting an Image and I am trying to flip it right or left. horizonal flip. I tried to do something like but don't have idea how to move forward

The size of the image is int height and int width and the function knows the values in pixels.

Here is my code:

void flip_hrizntal_pixels(struct Pixel **pixels, int height, int width)
{
    //Stuck here don't know how flip those pixels 
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            //pixels[i][j].red = 
            //pixels[i][j].green = 
            //pixels[i][j].blue = 
        }
    }

}

here are struct data:

struct Pixel
{
    unsigned char red;
    unsigned char green;
    unsigned char blue;
};
struct RGB_Image
{
    long height;
    long width;
    long size;
    struct Pixel **pixels;
};

i am calling this function like that :

struct RGB_Image image;
int status = load_image(&image); 
flip_hrizntal_pixels(image.pixels, image.height, image.width);

Upvotes: 1

Views: 3299

Answers (2)

Rotem
Rotem

Reputation: 32084

The following C code flips RGB image left/right:

//Flip RGB (or BGR) image Left/Right.
//P is an array of <height> pointers.
//P[0] points first pixel of first row.
//P[1] points first pixel of second row.
//P[height-1] points first pixel of last row.
static void flip_hrizntal_pixels(Pixel **P, int height, int width)
{
    //Allocate sketch buffer for storing single flipped row.
    Pixel *R = (Pixel*)malloc(width*sizeof(Pixel));

    //Stuck here don't know how flip those pixels 
    for (int i = 0; i < height; i++)
    {
        Pixel *I0 = P[i];    //Points first pixel in source image

        //j is destination index (index of rgb triple in source image I).
        for (int j = 0; j < width; j++)
        {
            //Iterate source row from end of row to beginning of row.
            R[j].red    = I0[width - j - 1].red;
            R[j].green  = I0[width - j - 1].green;
            R[j].blue   = I0[width - j - 1].blue;
        }

        //Copy flipped row back to image P.
        memcpy(I0, R, width*sizeof(Pixel));
    }

    free(R);
}

Before executing flip_hrizntal_pixels, you need to prepare an array of pointers.

Computing image stride in bytes:
stride is the number of bytes between two consecutive rows.
For BMP format, the stride must be a multiple of 4 (padded up, in case width is not a multiple of 4).

int stride = width*3;

//For supporting width that is not a multiple of 4, stride in bytes is padded up to nearest multiple of 4 bytes.
stride = (stride + 3) & (~3);  //http://mapw.elte.hu/elek/bmpinmemory.html

Preparing array of pointers to rows:
Assume I is a pointer to the input image.

//Prepare and array of pointers to rows:
//////////////////////////////////////////////////////////////////////////
//P[0] -> Points beginning of first row.
//P[1] -> Points beginning of second row.
//...
//P[height-1] -> Points beginning of last row.    
//Allocate array of <height> pointers.
Pixel **P = (Pixel**)malloc(height*sizeof(Pixel*));

for (int i = 0; i < height; i++)
{
    P[i] = (Pixel*)((char*)I + stride*i); //Advance by <stride> bytes from row to row.
}
//////////////////////////////////////////////////////////////////////////

Executing flip_hrizntal_pixels:

flip_hrizntal_pixels(P,
                     height, 
                     width);

Cleanup:

free(P);

Testing (peppers.png image from MATLAB):

Input image:
Before Flip

Output image:
After Flip

Upvotes: 1

ARD
ARD

Reputation: 48

Imagine that your picture is arranged as rows and columns of Pixels, each Pixel having R,G & B. Each row will have 'width' number of Pixels, and there will be such 'height' number of rows.

So, to flip on the horizontal i.e. rightmost Pixel in a row goes to the left-most and vice-versa, followed by 2nd Pixel in the same row which is exchanged with 2nd last Pixel, and so on, the code would be something like this. (PS: This is just a quick code to give you an idea how to proceed. I haven't compiled/run my code)

Hope this helps

void flip_hrizntal_pixels(struct Pixel **pixels, int height, int width)
{
Pixel tempPixel;

for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width/2; j++)
    {
    //make a temp copy of the 'j-th' Pixel  
    tempPixel.red = pixels[i][j].red; 
    tempPixel.green = pixels[i][j].green;  
    tempPixel.blue = pixels[i][j].blue; 


    //copy the corresponding last Pixel to the j-th pixel 
    pixels[i][j].red = pixels[i][width-j].red; 
    pixels[i][j].green = pixels[i][width-j].green; 
    pixels[i][j].blue = pixels[i][width-j].blue;


    //copy the temp copy that we made earlier of j-th Pixel to the corresponding last Pixel
    pixels[i][width-j].red = tempPixel.red;
    pixels[i][width-j].green = tempPixel.green;
    pixels[i][width-j].blue = tempPixel.blue;

    }
}

}

Upvotes: 2

Related Questions