2013-04-22 41 views
2

我必須編寫一個程序,在該程序中,我爲用戶輸入PPM圖像,然後從左到右鏡像圖像(基本上翻轉Y軸)。所以如果圖像是<,新圖像現在將>。這不應該是180度旋轉,因爲這會使圖像顛倒。它應該仍然是一樣的,只是反映出來。C - 從左到右鏡像PPM

我在這裏有代碼,我用來輸入和輸出PPM,但我不知道如何鏡像它。我做了一個理論上可用於鏡像代碼的函數,但我不確定這是否是最好的方法。如果你知道一個更好的地方放置代碼,請成爲我的客人。

我已經研究了這個話題,但只能找到人們需要旋轉圖像的問題。

這是我到目前爲止有:

#include<stdio.h> 
#include<stdlib.h> //for fopen() 

typedef struct { 
    unsigned char red,green,blue; 
} pixel_t; //struct for pixels 

typedef struct { 
    int x, y; 
    pixel_t *data; 
} PPMImage; //struct for creating the image 

#define RGB_COMPONENT_COLOR 255 

static PPMImage *readPPM(const char *filename) 
{ 
    char buff[16]; 
    PPMImage *img; 
    FILE *fp; 
    int c, rgb_comp_color; 

    fp = fopen(filename, "rb"); 
    if (!fp) { 
     fprintf(stderr, "Unable to open file '%s'\n", filename); 
     exit(1);} //opens the ppm and checks to make sure it can be opened 

    if (!fgets(buff, sizeof(buff), fp)) { 
     perror(filename); 
     exit(1);} //read the format of the image 

    if (buff[0] != 'P' || buff[1] != '6') { 
     fprintf(stderr, "Invalid image format (must be 'P6')\n"); 
     exit(1);} //checks to see if the format is ppm 

    img = (PPMImage *)malloc(sizeof(PPMImage)); 
    if (!img) { 
     fprintf(stderr, "Unable to allocate memory\n"); 
     exit(1);} //allocates the memory needed to form the input image 

    c = getc(fp); 
    while (c == '#') { 
    while (getc(fp) != '\n') ; 
     c = getc(fp); 
    }//checks for comments 

    ungetc(c, fp); 

    if (fscanf(fp, "%d %d", &img->x, &img->y) != 2) { 
     fprintf(stderr, "Invalid image size (error loading '%s')\n", filename); 
     exit(1);} //reads the size of the image, height becomes img->y, and width becomes img->x 

    if (fscanf(fp, "%d", &rgb_comp_color) != 1) { 
     fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename); 
     exit(1);} //reads how much of each color there is 

    if (rgb_comp_color!= RGB_COMPONENT_COLOR) { 
     fprintf(stderr, "'%s' does not have 8-bits components\n", filename); 
     exit(1);} //makes sure the the component is 8 bits 

    while (fgetc(fp) != '\n') ; 

    img->data = (pixel_t*)malloc(img->x * img->y * sizeof(pixel_t)); 

    if (!img) { 
     fprintf(stderr, "Unable to allocate memory\n"); 
     exit(1);} //allocates the memory need for the pixel data 

    if (fread(img->data, 3 * img->x, img->y, fp) != img->y) { 
     fprintf(stderr, "Error loading image '%s'\n", filename); 
     exit(1);} //reads the pixel data 

    fclose(fp); 
    return img; 
} 
void writePPM(const char *filename, PPMImage *img) 
{ 
    FILE *fp; 

    fp = fopen(filename, "wb"); 
    if (!fp) { 
     fprintf(stderr, "Unable to open file '%s'\n", filename); 
     exit(1);} //opens the file for output 

    //write the header file 
    //image format 
    fprintf(fp, "P6\n"); 

    //image size 
    fprintf(fp, "%d %d\n",img->x,img->y); 

    // rgb component depth 
    fprintf(fp, "%d\n",RGB_COMPONENT_COLOR); 

    // pixel data 
    fwrite(img->data, 3 * img->x, img->y, fp); 
    fclose(fp); 
} 

void mirror(PPMImage *img) 
{ 

//this is where I want to insert the code for mirroring the image 

} 

int main(int argc, char* argv[]){ //takes command line parameters 
    PPMImage *image; 
    char* filename = argv[1]; 
    image = readPPM(filename); 
    mirror(image); 
    writePPM("OutputFile.ppm",image); //creates the output file 
    printf("Press Enter"); 
    getchar(); 
} 
+0

這等同於字符串反轉字符的通病。對你無法自己解決它感到羞恥。 – 2013-04-22 14:27:23

+0

儘管這個問題提出了一個框架程序,但它要求將一段代碼插入到該程序中,而沒有任何嘗試解決方案或理解的示範,所以它基本上是一個「爲我編寫代碼」的問題。 – Kaz 2013-11-14 20:24:08

回答

4

你的鏡子()函數可以一次對圖像的一行工作。對於每一行,取該行中最左邊的像素,並將其值與該行中最右側像素的值交換。然後取第二個最左邊的像素,並將其值與第二個最右邊的像素交換,依此類推,直到您交換的像素的列位置「在中間相遇」。 (然後移動到下一行並做相同的事情,直到完成所有行)。

請注意,如果圖像包含奇數列,則圖像中心會有一列保持未修改狀態(因爲它形成鏡像發生的軸)。偶數列,所有列將被交換。

+0

這就像反轉一個字符串。 – 2013-04-22 14:26:04

0

要鏡像圖像垂直您可以使用此功能:

void mirrorVert(PPMImage *img) 
{ 
    int y; 
    int x; 
    const int middleX = img->x/2; 
    pixel_t tmp; 
    pixel_t* p; 

    for (y = 0; y < img->y; ++y) 
    { 
     p = img->data + y * img->x; 
     for (x = 0; x < middleX; ++x) 
     { 
      // swap pixels 
      tmp = p[x]; 
      p[x] = p[img->x - 1 - x]; 
      p[img->x - 1 - x] = tmp; 
     } 
    } 
} 

並將其水平反映:

void mirrorHoriz(PPMImage *img) 
{ 
    const int line_size = img->x * sizeof(pixel_t); 
    const int middle = img->y/2; 
    int y; 

    // allocate swap buffer 
    pixel_t* buff = (pixel_t*)malloc(line_size); 
    pixel_t* top; 
    pixel_t* bottom; 

    for (y = 0; y < middle; ++y) 
    { 
     // swap lines from top and bottom 
     top = img->data + (y * img->x); 
     bottom = img->data + ((img->y - y - 1) * img->x); 

     memcpy(buff, top, line_size); 
     memcpy(top, bottom, line_size); 
     memcpy(bottom, buff, line_size); 
    } 

}