PPM圖像格式(Portable Pixelmap)

參考:

Netpbm項目主頁: http://sourceforge.NET/projects/netpbm

Netpbm wiki: http://en.wikipedia.org/wiki/Netpbm

Netpbm format wiki: http://en.wikipedia.org/wiki/Netpbm_format

ppm文件格式: http://hi.baidu.com/sunboya198/item/80fb8e16d39ae9098fbde4d6

1. PPM介紹

PPM(Portable PixMap)是portable像素圖片,是有netpbm項目定義的一系列的portable圖片格式中的一個。這些圖片格式都相對比較容易處理,跟平臺無關,所以稱之爲portable,簡單理解,就是比較直接的圖片格式,比如PPM,其實就是把每一個點的RGB分別保存起來。所以,PPM格式的文件是沒有壓縮的,相對比較大,但是由於圖片格式簡單,一般作爲圖片處理的中間文件(不會丟失文件信息),或者作爲簡單的圖片格式保存。

2. PPM格式分析

netpbm的幾種圖片格式是通過其表示的顏色類型來區別的,PBM是位圖,只有黑色和白色,PGM是灰度圖片,PPM是代表完整的RGB顏色的圖片。

(1) 文件頭

文件頭由三個部分(或者認爲是四個部分)組成:這幾個部分之間用回車或換行分隔(但是PPM標準中要求是空格)

第一部分是文件magic number:

每一個netpbm圖片由兩個字節的magic number (ASCII)組成,來標識文件的類型(PMB/PGM/PPM)以及文件的編碼(ASCII或binary).

所以PPM格式的起始兩個字節爲P3或者P6.

關於編碼(ASCII或binary): 其區別是ASCII編碼的文件是對於閱讀友好的,可以字節用文本編輯器打開,並讀取其對應的圖片的數據(比如RGB的值),然後中間會有空格回車等隔開。binary就是按照二進制的形式,順序存儲圖片信息,沒有空格回車分隔。所以很顯然,binary格式的圖片處理起來更快(不需要判斷空格回車),而且圖片會更小,但是ASCII閱讀調試更爲直接。

第二部分是圖像寬度和高度(空格隔開),用ASCII表示。

第三部分是描述像素的最大顏色組成,允許描述超過一個字節(0-255)的顏色值。

另外,在上面的三個部分裏面,都可以使用"#"插入註釋,註釋是#到行尾(回車或換行)部分。

(2) 圖像數據部分

對於ASCII格式,就是按照RGB的順序排列,以ASCII存儲,並且,RGB中間用空格隔開,圖片每一行用回車隔開。

對於binary格式,就是每一個像素點的RGB值分別順序存儲並且按二進制寫入文件(fwrite),沒有任何分隔。

比如下面這個圖片 (一共六個像素點,圖片寬度爲3,高度爲2):

代碼如下:

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. int writePPMHeader(FILE *f, char magic, int w, int h, int color) {  
  5.     if (f==NULL) {  
  6.         printf("FILE error\n");  
  7.         exit(0);  
  8.     }  
  9.   
  10.     if (magic=='A') {// ASCII  
  11.         fprintf(f, "P3\n");  
  12.     } else if (magic=='B') {  
  13.         fprintf(f, "P6\n");  
  14.     } else {  
  15.         printf("Magic can only be A(ASCII) or B(binary)\n");  
  16.         exit(0);  
  17.     }  
  18.   
  19.     fprintf(f, "%d %d\n", w, h);  
  20.     fprintf(f, "%d\n", color);  
  21.     return 0;  
  22. }  
  23.   
  24. int writePPMdataP3(FILE* f, unsigned char* img, int w, int h) {  
  25.     int i,j;  
  26.     for(i=0;i<h;i++) {   // every rwo  
  27.         for(j=0;j<w;j++) {   // every line  
  28.             fprintf(f, "%d ",img[i*w*3+3*j]);  
  29.             fprintf(f, "%d ",img[i*w*3+3*j+1]);  
  30.             fprintf(f, "%d ",img[i*w*3+3*j+2]);<span style="white-space:pre">   </span>// PS: 對於j=w-1的時候,最後一個空格可以不寫,但是這裏就不考慮了  
  31.         }  
  32.         fprintf(f, "\n");  
  33.     }  
  34. }  
  35.   
  36. int writePPMdataP6(FILE* f, unsigned char* img, int w, int h) {  
  37.     int i,j;  
  38.     for(i=0;i<w;i++) {  
  39.         for(j=0;j<h;j++) {  
  40.             fwrite(img, w*h, 3, f);  
  41.         }  
  42.     }  
  43. }  
  44.   
  45. #define WIDTH   3  
  46. #define HEIGHT  2  
  47. unsigned char img[WIDTH*HEIGHT*3]={255,0,0,0,255,0,0,0,255,255,255,0,255,255,255,0,0,0};  
  48.   
  49. int main() {  
  50.     char *filename1 = "testP3.ppm";  
  51.     char *filename2 = "testP6.ppm";  
  52.   
  53.     FILE *f3 = fopen(filename1, "w");  
  54.     if (f3==NULL) {  
  55.         printf("FILE error\n");  
  56.         exit(0);  
  57.     }  
  58.   
  59.     FILE *f6 = fopen(filename2, "w");  
  60.     if (f6==NULL) {  
  61.         printf("FILE error\n");  
  62.         exit(0);  
  63.     }  
  64.   
  65.     writePPMHeader(f3, 'A', WIDTH, HEIGHT, 255);  
  66.     writePPMdataP3(f3, img, WIDTH, HEIGHT);  
  67.   
  68.     writePPMHeader(f6, 'B', WIDTH, HEIGHT, 255);  
  69.     writePPMdataP6(f6, img, WIDTH, HEIGHT);  
  70.   
  71.     fclose(f3);  
  72.     fclose(f6);  
  73.   
  74.     return 0;  
  75. }  

測試如下:

PPM文件格式分三種:

1. PPM灰度文件
  文件頭由3行文本組成,可由fgets讀出
  1)第一行爲“P2",表示文件類型
  2)第二行爲圖像的寬度和高度
  3)第三行爲最大的象素值255
  接下來是圖像數據塊。按行順序存儲。每個象素佔4個字節,灰度通道爲4字節ASCII碼錶示的整數,高字節在前。左上角爲座標原點。

2. 16位PPM文件(至少適用於讀取由DCRAW生成的PPM文件)
  文件頭由3行文本組成,可由fgets讀出
  1)第一行爲“P6",表示文件類型
  2)第二行爲圖像的寬度和高度
  3)第三行爲最大的象素值
  接下來是圖像數據塊。按行順序存儲。每個象素佔3個字節,依次爲紅綠藍通道,每個通道爲1字節整數。左上角爲座標原點。

3. PPM彩色文件
  文件頭由3行文本組成,可由fgets讀出
  1)第一行爲“P3",表示文件類型
  2)第二行爲圖像的寬度和高度
  3)第三行爲最大的象素值255
  接下來是圖像數據塊。按行順序存儲。每個象素佔12個字節,依次爲紅綠藍通道,每個通道爲4字節ASCII碼錶示的整數,高字節在前。左上角爲座標原點。

  可移植像素圖格式(PPM),可移植灰度圖格式(PGM)和可移植位圖格式(PBM)是便於跨平臺的圖像格式。有時候也被統稱爲PNM格式。

歷史

  PBM格式由Jef Poskanzer在20世紀80年代發明,爲了便於通過電子郵件,用ASCII碼錶示單色位圖,能夠承受一般的文本格式的變動。

  第一個處理PBM格式的工具庫是Pbmplus。它由這個格式的發明人Jef Poskanzer開發,在1988年發佈。主要包含Jef編寫的將PBM轉化爲已存在的其他圖像格式的工具。在1988年末,Jef開發出PGM、PPM格式以及相關工具,並加入Pbmplus中。Pbmplus的最終發佈日期是1991年12月10日。

  在1993年,Netpbm庫開始開發,用來替代不再維護的Pbmplus。它是Pbmplus的簡單的重新包裝,附加全世界開發者提供的額外功能和修訂,可能是目前用的最普遍的處理PBM、PGM和PPM格式的工具庫。

文件格式描述

  這三種格式在顏色的表示上有差異。PBM是單色,PGM是灰度圖,PPM使用RGB顏色。

  每個文件的開頭兩個字節(ASCII碼)作爲文件描述子,指出具體格式和編碼形式。具體見下表:

文件描述子類型編碼
P1位圖ASCII
P2灰度圖ASCII
P3像素圖ASCII
P4位圖二進制
P5灰度圖二進制
P6像素圖二進制

發佈了14 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章