zoukankan      html  css  js  c++  java
  • 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);
    }
    
  • 相关阅读:
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    MFC/.NET
    学习小结——记于华为2018届校园招聘宣讲会之后
    槽点今天未想到
  • 原文地址:https://www.cnblogs.com/oloroso/p/5846623.html
Copyright © 2011-2022 走看看