2010-04-22 37 views
8

Tôi cần đọc một tệp PPM và lưu trữ nó trong một mảng được viết bằng C. Ai đó có thể giúp tôi thực hiện việc này không?đọc tệp PPM và lưu trữ nó trong một mảng; được mã hóa với C

Cảm ơn rất nhiều.

+0

Bạn đang gặp sự cố gì? Nếu bạn đăng nỗ lực của bạn vào nó mà không hoạt động đúng, nó sẽ được dễ dàng, đủ để tìm lỗi (s). – caf

Trả lời

3

Đây là PPM specification.

Tệp PPM được xây dựng trong 9 phần được phân tách bằng khoảng trắng.

  • Mở tệp
  • đọc cho đến khi khoảng trắng đầu tiên và kiểm tra xem bạn có P6. Sau đó bỏ qua các khoảng trắng khác.
  • đọc cho đến khi khoảng trắng tiếp theo, chuyển đổi bộ đệm của bạn thành chiều rộng nguyên. Sau đó bỏ qua các khoảng trắng khác
  • đọc cho đến khi khoảng trắng tiếp theo, chuyển bộ đệm của bạn thành chiều cao nguyên. Sau đó, bỏ qua khoảng trắng khác
  • phân bổ một mảng 2D của số nguyên trong kích thước của chiều cao * chiều rộng
  • đọc max-val
  • dòng
  • đọc bởi dòng và điền các mảng
+2

Tôi nghĩ rằng bạn cần phải làm rõ những gì đang xảy ra trong câu trả lời này, nó không phải là rất rõ ràng. –

+1

Điều này sẽ không thành công trên nhiều tệp PNM vì nó không tính đến dòng nhận xét. – deegee

18

Các mã sau cho thấy cách đọc, thay đổi màu pixel và viết một hình ảnh ở định dạng PPM . Tôi hy vọng nó sẽ giúp.

#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

Mã này sẽ không thành công trên nhiều tệp PNM vì PNM sử dụng khoảng trống giữa các mục nhập tiêu đề và không được cố định để chỉ sử dụng LF. Một dòng chú thích cũng có thể được đặt gần như bất cứ nơi nào trong tiêu đề và về mặt kỹ thuật là dòng duy nhất phải được kết thúc bằng một CR hoặc LF. Thiết kế định dạng tệp nhị phân PNM là một mớ hỗn độn bị hỏng. Netpbm sourceforge thậm chí nói rằng việc đưa vào một bình luận, mặc dù nó là một đối tượng header hợp lệ, về cơ bản phá vỡ định dạng tệp. – deegee

+1

bạn có mallocs, tại sao không có giải thoát? – imre

Các vấn đề liên quan