ppm图像相关

PPM图像格式介绍

直接拿具体的数据来说明是最直接的,使用ue打开ppm文件,采用的都是十六进制asc码表示的,这里要注意地址00000000h中的最后一个字母是始终不变的,这原来没注意晕了我好久,第一行

50=P,

36=6,

20=空格,

直到255后面的0A=换行

之后就是数据B3 B3 B3分别对应第一个像素的rgb通道,

再之后是第二个像素的rgb通道

直到图像中第一行所有的数据都存进来,网上有人说每一行后面有个回车换行,事实上打开的文件一共是ecb8=60600行,再乘以每行十六个数(f),一共有969600个数据,正好等于800*404*3,所以事实上我做使用的p6格式的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 NumberTypeEncoding
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部分:P3P6,指明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);
}



参考网址:
https://www.cnblogs.com/oloroso/p/5846623.html?utm_source=itdadao&utm_medium=referral
https://blog.csdn.net/kinghzkingkkk/article/details/70226214

posted on 2018-10-17 19:05  悟江居士  阅读(905)  评论(0编辑  收藏  举报

导航