• PPM图片格式及其C读写代码


    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部分: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
    ", 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
    %d %d
    255
    ",w,h);
    
        // 写RGB数据
        fwrite(data, w*h*3, 1, fp);
    
        fclose(fp);
    }
    
  • 相关阅读:
    PAT (Advanced Level) 1086. Tree Traversals Again (25)
    PAT (Advanced Level) 1085. Perfect Sequence (25)
    PAT (Advanced Level) 1084. Broken Keyboard (20)
    PAT (Advanced Level) 1083. List Grades (25)
    PAT (Advanced Level) 1082. Read Number in Chinese (25)
    HDU 4513 吉哥系列故事――完美队形II
    POJ Oulipo KMP 模板题
    POJ 3376 Finding Palindromes
    扩展KMP
    HDU 2289 Cup
  • 原文地址:https://www.cnblogs.com/oloroso/p/5846623.html
Copyright © 2020-2023  润新知