PPM圖像格式介紹
PPM圖像格式是由Jef Poskanzer 大叔,在我出生那一年,也就是1991年所創造的,碰巧的是PPM也是天蠍座。
PPM(Portable Pixmap Format)還有兩位兄長,大哥名叫「PBM」,二哥人稱「PGM」,他們三兄弟各有所長,下面為你們一一介紹:
- PBM 是位圖(bitmap),僅有黑與白,沒有灰
- PGM 是灰度圖(grayscale)
- PPM 是通過RGB三種顏色顯現的圖像(pixmaps)
每個圖像文件的開頭都通過2個字節「magic number」來表明文件格式的類型(PBM, PGM, PPM),以及編碼方式(ASCII 或 Binary),magic number分別為P1、P2、P3、P4、P5、P6。
| Magic Number | Type | Encoding |
|---|---|---|
| P1 | Bitmap | ASCII |
| P2 | Graymap | ASCII |
| P3 | Pixmap | ASCII |
| P4 | Bitmap | Binary |
| P5 | Graymap | Binary |
| P6 | Pixmap | Binary |
編碼方式
ASCII格式適合人類閱讀理解,可以用文本編輯器打開,讀取對應圖像的數據(比如PPM格式的RGB值)。 Binary格式適合機器閱讀,按照二進制形式,順序存儲圖像信息,不用空格分隔,所以圖像處理起來更有效率,占用空間容量更少(由於缺少空格)。
下面着重講解PPM格式:
PPM圖像格式分為兩部分,分別為頭部分和圖像數據部分。
頭部分:由3部分組成,通過換行或空格進行分割,一般PPM的標准是空格。
第1部分:P3或P6,指明PPM的編碼格式,
第2部分:圖像的寬度和高度,通過ASCII表示,
第3部分:最大像素值,0-255字節表示。
在這三部分中,可能會有注釋。注釋以#開頭,例如:# CREATOR: GIMP PNM Filter Version 1.1。
圖像數據部分:
ASCII格式:按RGB的順序排列,RGB中間用空格隔開,圖片每一行用回車隔開。
Binary格式:PPM用24bits代表每一個像素,紅綠藍分別占用8bits。
舉例:
P3 3 2 255
255 0 0 0 255 0 0 0 255 255 255 0 255 255 255 0 0 0
- P3: PPM編碼格式為ASCII
- 3: 3列像素
- 2: 2行像素
- 255: 最大像素值
C語言讀寫代碼
// 從文件讀取PPM圖片
void ppm_load(char* filename, unsigned char* out_data, int* w, int* h)
{
char header[1024];
FILE* fp = NULL;
int line = 0;
fp = fopen(filename, "rb");
// 讀取圖片格式(例如:"P6")
// 高寬在第二行非注釋數據
while(line < 2){
fgets(header, 1024, fp);
if(header[0] != '#'){
++line;
}
}
// 讀取寬高
sscanf(header,"%d %d\n", w, h);
// 獲取最大像素值
fgets(header, 20, fp);
// get rgb data
fread(*data, (*w)*(*h)*3, 1, fp);
fclose(fp);
}
// 寫ppm圖像到文件
void ppm_save(char* filename, unsigned char* data, int w, int h)
{
FILE* fp;
char header[20];
fp = fopen(filename, "wb");
// 寫圖片格式、寬高、最大像素值
fprintf(fp,"P6\n%d %d\n255\n",w,h);
// 寫RGB數據
fwrite(data, w*h*3, 1, fp);
fclose(fp);
}
