перевернуть изображение BMP по горизонтали в c - PullRequest
1 голос
/ 02 июня 2019

Моя функция - получать изображение, и я пытаюсь перевернуть его вправо или влево.горизонтальный флип.Я пытался сделать что-то вроде, но не знаю, как двигаться вперед

Размер изображения - это int высота и int ширина, и функция знает значения в пикселях.

Вотмой код:

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 = 
        }
    }

}

вот данные структуры:

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

Я вызываю эту функцию так:

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

Ответы [ 2 ]

2 голосов
/ 02 июня 2019

Представьте, что ваша картинка организована в виде строк и столбцов пикселей, каждый пиксель имеет R, G и B. Каждая строка будет иметь число пикселей в ширину, и будет такое количество строк в высоту.

Таким образом, чтобы перевернуть горизонтальный, т. Е. Самый правый пиксель в строке, переходит в крайний левый угол и наоборот, за которым следует второй пиксель в той же строке, который заменяется вторым последним пикселем, и т. Д., Код будет быть примерно таким (PS: Это всего лишь быстрый код, чтобы дать вам представление о том, как действовать. Я не скомпилировал / не запустил свой код)

Надеюсь, это поможет

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;

    }
}

}

1 голос
/ 02 июня 2019

Следующий код C переворачивает RGB-изображение влево / вправо:

//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);
}

Перед выполнением flip_hrizntal_pixels необходимо подготовить массив указателей.

Вычисление шага изображения в байтах:
stride - это количество байтов между двумя последовательными строками.
Для формата BMP значение stride должно быть кратно 4 (дополнено доширина корпуса не кратна 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

Подготовка массива указателей на строки:
Предположим, I - указатель на входное изображение.

//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.
}
//////////////////////////////////////////////////////////////////////////

Выполнение flip_hrizntal_pixels:

flip_hrizntal_pixels(P,
                     height, 
                     width);

Очистка:

free(P);

Тестирование (peppers.png изображение из MATLAB):

Входное изображение:
Before Flip

Выходное изображение:
After Flip

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...