2010-04-22 2 views

답변

3

여기는 PPM specification입니다.

PPM 파일은 공백으로 구분 된 9 개의 섹션으로 구성됩니다.

  • 파일을 엽니 다
  • 첫 번째 공백까지 읽기 및 P6있어 확인. 그런 다음 다른 공백을 건너 뜁니다.
  • 다음 공백까지 읽기, 버퍼를 정수 너비로 변환하십시오. 그런 다음 다른 공백을 건너 뜁니다.
  • 다음 공백까지 읽을 수 있도록 버퍼를 정수 높이로 변환하십시오. 이어서
  • 라인에 의해 MAX-브로
  • 판독 라인을 판독 높이 * 폭
  • 의 크기의 정수의 2 차원 배열을 할당 다른 화이트 스페이스를 생략하고 어레이
+2

이 답변에서 어떤 일이 일어나는지 분명히해야한다고 생각합니다. 명확하지 않습니다. –

+1

주석 행을 고려하지 않으므로 많은 PNM 파일에서 실패합니다. – deegee

18

에게 다음 코드를 작성 읽기, 픽셀 색 변경 및 이미지를 PPM 형식으로 작성하는 방법을 보여줍니다. 나는 그것이 도움이되기를 바랍니다.

#include<stdio.h> 
#include<stdlib.h> 

typedef struct { 
    unsigned char red,green,blue; 
} PPMPixel; 

typedef struct { 
    int x, y; 
    PPMPixel *data; 
} PPMImage; 

#define CREATOR "RPFELGUEIRAS" 
#define RGB_COMPONENT_COLOR 255 

static PPMImage *readPPM(const char *filename) 
{ 
     char buff[16]; 
     PPMImage *img; 
     FILE *fp; 
     int c, rgb_comp_color; 
     //open PPM file for reading 
     fp = fopen(filename, "rb"); 
     if (!fp) { 
       fprintf(stderr, "Unable to open file '%s'\n", filename); 
       exit(1); 
     } 

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

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

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

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

    ungetc(c, fp); 
    //read image size information 
    if (fscanf(fp, "%d %d", &img->x, &img->y) != 2) { 
     fprintf(stderr, "Invalid image size (error loading '%s')\n", filename); 
     exit(1); 
    } 

    //read rgb component 
    if (fscanf(fp, "%d", &rgb_comp_color) != 1) { 
     fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename); 
     exit(1); 
    } 

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

    while (fgetc(fp) != '\n') ; 
    //memory allocation for pixel data 
    img->data = (PPMPixel*)malloc(img->x * img->y * sizeof(PPMPixel)); 

    if (!img) { 
     fprintf(stderr, "Unable to allocate memory\n"); 
     exit(1); 
    } 

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

    fclose(fp); 
    return img; 
} 
void writePPM(const char *filename, PPMImage *img) 
{ 
    FILE *fp; 
    //open file for output 
    fp = fopen(filename, "wb"); 
    if (!fp) { 
     fprintf(stderr, "Unable to open file '%s'\n", filename); 
     exit(1); 
    } 

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

    //comments 
    fprintf(fp, "# Created by %s\n",CREATOR); 

    //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 changeColorPPM(PPMImage *img) 
{ 
    int i; 
    if(img){ 

     for(i=0;i<img->x*img->y;i++){ 
       img->data[i].red=RGB_COMPONENT_COLOR-img->data[i].red; 
       img->data[i].green=RGB_COMPONENT_COLOR-img->data[i].green; 
       img->data[i].blue=RGB_COMPONENT_COLOR-img->data[i].blue; 
     } 
    } 
} 

int main(){ 
    PPMImage *image; 
    image = readPPM("can_bottom.ppm"); 
    changeColorPPM(image); 
    writePPM("can_bottom2.ppm",image); 
    printf("Press any key..."); 
    getchar(); 
} 
+1

PNM은 헤더 항목 사이에 공백을 사용하고 LF 만 사용하도록 고정되어 있지 않으므로이 코드는 많은 PNM 파일에서 실패합니다. 주석 행은 헤더의 거의 모든 위치에 배치 할 수 있으며 기술적으로 CR 또는 LF로 끝나야하는 유일한 행입니다. PNM 이진 파일 형식 디자인은 망가진 혼란입니다. sourceforge netpbm은 심지어 주석을 포함하는 것이 유효한 헤더 객체 임에도 불구하고 본질적으로 파일 형식을 깨뜨린다고합니다. – deegee

+1

당신은 mallocs를 가지고 있는데 왜 자유가 없습니까? – imre

관련 문제