2010-04-22 25 views
8

ile kodlanmış Bir PPM dosyasını okumalı ve onu C'ye yazılan bir dizide saklamalıyım. Bunu yapmama yardım eden var mı?PPM dosyasını okuyun ve bir dizide saklayın; C

Çok teşekkürler.

+0

Hangi kısımda sorun yaşıyorsunuz? Eğer denemenizi doğru şekilde yayınlamıyorsanız, bu doğru çalışmıyorsa, hataları bulmak için yeterince kolay olacaktır. – caf

cevap

3

İşte PPM specification.

PPM dosyası beyaz boşluklarla ayrılmış 9 bölüme ayrılmıştır.

  • Açık dosya
  • ilk beyaz boşluk kadar okuma ve P6 var kontrol edin. Sonra diğer beyaz boşlukları atlayın.
  • Bir sonraki beyaz alana kadar okuyun, arabellek bir tamsayı genişliğine dönüştürün. Daha sonra diğer beyaz boşlukları
  • bir sonraki beyaz alana kadar okuyun, arabelleğinizi bir tamsayı yüksekliğine dönüştürün. Daha sonra
  • hattı ile maks-val
  • okuma satırını okumak yüksekliği * genişlik
  • büyüklüğünde bir tamsayı 2B dizi tahsis diğer beyaz boşluk atlama ve dizi
+2

Bu cevapta neler olup bittiğini açıklığa kavuşturmanız gerektiğini düşünüyorum, bu çok açık değil. –

+1

Bu, pek çok PNM dosyasında, yorum satırlarını hesaba katmadığından başarısız olur. – deegee

18

aşağıdaki kodu dolgu piksel rengini okuma, değiştirme, görüntüyü PPM biçiminde gösterir. Umut ediyorum bu yardım eder.

#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

Bu kod, birçok PNM dosyasında başarısız olacaktır, çünkü PNM, başlık girişleri arasındaki boşluğu kullanır ve yalnızca LF'yi kullanacak şekilde sabitlenmez. Bir yorum satırı, başlığın hemen hemen her yerinde bulunabilir ve teknik olarak bir CR veya LF ile sonlandırılması gereken tek satırdır. PNM ikili dosya formatı tasarımı kırık bir karmaşadır. Sourceforge netpbm, geçerli bir başlık nesnesi olsa bile, bir yorum eklemenin aslında dosya biçimini kırdığını belirtir. – deegee

+1

Malloglarınız var, neden serbest değilsiniz? – imre

İlgili konular