ppm图片有2种格式, ASCII格式和binary格式.
(1)ppm头部分
由三部分组成,这三部分由回车或换行分割,但PPM的标准中是要求空格。
第一行通常是P3或P6,说明是PPM格式;
第二行是图象的宽度和高度,用ASCII来表示;
第三行是描述像素的最大颜色组成,这里允许描述超过一个字节(0-255)的颜色值。
另外可以在上面个部分的后面用#来追加注释,注释行是从#到该行末。
(2) 图像数据部分
对于ASCII格式,就是按照RGB的顺序排列,以ASCII存储,并且,RGB中间用空格隔开,图片每一行用回车隔开。
对于binary格式,就是每一个像素点的RGB值分别顺序存储并且按二进制写入文件(fwrite),没有任何分隔。
比如下面这个图片 (一共六个像素点,图片宽度为3,高度为2):
ASCII格式ppm: [R G B\n]
P3 #ASCII格式图片为 p3 64 64 #width height 255 #RGB 255 0 0 255 0 0 ...... 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0
以上为纯红色64*64图片, 文件共4099行, 除3行头文件, "255 0 0"有 64*64行
binary格式ppm: [RGB值顺序存储,无任何分隔]
0000000: 5036 0a36 3420 3634 0a32 3535 0aff 0000 P6.64 64.255.... 0000010: ff00 00ff 0000 ff00 00ff 0000 ff00 00ff ................ 0000020: 0000 ff00 00ff 0000 ff00 00ff 0000 ff00 ................ 0000030: 00ff 0000 ff00 00ff 0000 ff00 00ff 0000 ................ 0000040: ff00 00ff 0000 ff00 00ff 0000 ff00 00ff ................
以上为纯红色64*64图片, 二进制文件
P6 表示二进制图片, 文件头为13位, 读取文件数据部分定位使用 fseek(fp, 13, 0);
生成纯色图片代码:
1 #include <stdio.h> 2 3 #define _VPATH "./../cfg/" 4 5 #define _B 1 6 #define PICNUM 5 7 8 int main(int argc, char *argv[]) 9 { 10 if(argc != 2) 11 { 12 printf("please argc 0 or 1\n"); 13 printf("0: binary image\n"); 14 printf("1: decimal image\n"); 15 return 0; 16 } 17 18 int iflag = atoi(argv[1]); 19 20 int i, k; 21 unsigned char r[PICNUM] = {0xFF, 0xFF, 0x0, 0x0, 0xFF}; 22 unsigned char g[PICNUM] = {0x0, 0xFF, 0x0, 0x0, 0xFF}; 23 unsigned char b[PICNUM] = {0x0, 0x0, 0xFF, 0x0, 0xFF}; 24 FILE *fp; 25 char fname[PICNUM][100]; 26 27 if(iflag == 0) 28 { 29 sprintf(fname[0], "%s%s", _VPATH, "B_red.ppm"); 30 sprintf(fname[1], "%s%s", _VPATH, "B_yellow.ppm"); 31 sprintf(fname[2], "%s%s", _VPATH, "B_blue.ppm"); 32 sprintf(fname[3], "%s%s", _VPATH, "B_black.ppm"); 33 sprintf(fname[4], "%s%s", _VPATH, "B_white.ppm"); 34 } 35 36 if(iflag == 1) 37 { 38 sprintf(fname[0], "%s%s", _VPATH, "D_red.ppm"); 39 sprintf(fname[1], "%s%s", _VPATH, "D_yellow.ppm"); 40 sprintf(fname[2], "%s%s", _VPATH, "D_blue.ppm"); 41 sprintf(fname[3], "%s%s", _VPATH, "D_black.ppm"); 42 sprintf(fname[4], "%s%s", _VPATH, "D_white.ppm"); 43 } 44 45 for(k = 0; k < PICNUM; k++) 46 { 47 48 if(iflag == 0) 49 { 50 fp = fopen(fname[k], "wb"); 51 if(fp == NULL) 52 { 53 printf("ERR001: open file error [%s]\n", fname); 54 return 0; 55 } 56 fprintf(fp, "%s\n", "P6"); 57 fprintf(fp, "%s\n", "64 64"); 58 fprintf(fp, "%s\n", "255"); 59 for(i = 0; i < 64 * 64; i++) 60 { 61 fwrite(&r[k], 1, 1, fp); 62 fwrite(&g[k], 1, 1, fp); 63 fwrite(&b[k], 1, 1, fp); 64 } 65 fclose(fp); 66 } 67 68 if(iflag == 1) 69 { 70 fp = fopen(fname[k], "w"); 71 if(fp == NULL) 72 { 73 printf("ERR001: open file error [create_ppm]\n"); 74 return 0; 75 } 76 fprintf(fp, "%s\n", "P3"); 77 fprintf(fp, "%s\n", "64 64"); 78 fprintf(fp, "%s\n", "255"); 79 for(i = 0; i < 64 * 64; i++) 80 { 81 fprintf(fp, "%d %d %d\n", r[k], g[k], b[k]); 82 } 83 fclose(fp); 84 } 85 } 86 return 1; 87 }
1 if(iflag == 3) 2 { 3 int c; 4 char fname_D[100]; 5 int w = 50, h = 50; 6 sprintf(fname_D, "%s%s", _VPATH, "D_image.ppm"); 7 8 fp = fopen(fname_D, "w"); 9 if(fp == NULL) 10 { 11 printf("ERR003: open file error [%s]\n", fname_D); 12 return 0; 13 } 14 fprintf(fp, "%s\n", "P3"); 15 fprintf(fp, "%s\n", "150 100"); 16 fprintf(fp, "%s\n", "255"); 17 for(i = 0; i < h; i++) 18 { 19 for(c = 0; c < w; c++) 20 { 21 fprintf(fp, "%d %d %d\n", 0xFF, 0x0, 0x0); 22 } 23 for(c = 0; c < w; c++) 24 { 25 fprintf(fp, "%d %d %d\n", 0xFF, 0xFF, 0x0); 26 } 27 for(c = 0; c < w; c++) 28 { 29 fprintf(fp, "%d %d %d\n", 0xFF, 0xF1, 0xFF); 30 } 31 } 32 33 for(i = 0; i < h; i++) 34 { 35 for(c = 0; c < w; c++) 36 { 37 fprintf(fp, "%d %d %d\n", 0x0, 0x0, 0xFF); 38 } 39 for(c = 0; c < w; c++) 40 { 41 fprintf(fp, "%d %d %d\n", 0xFF, 0x1F, 0xFF); 42 } 43 for(c = 0; c < w; c++) 44 { 45 fprintf(fp, "%d %d %d\n", 0x0, 0xa0, 0x0); 46 } 47 } 48 fclose(fp); 49 50 }
时间: 2024-10-26 00:36:05