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 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);
} 参考网址:
https://www.cnblogs.com/oloroso/p/5846623.html?utm_source=itdadao&utm_medium=referral
https://blog.csdn.net/kinghzkingkkk/article/details/70226214

ppm图像相关的更多相关文章

  1. WPF图形图像相关类

    BitmapMetadata类: 继承自抽象类ImageMetadata,包含图像的原数据信息,如相机型号.图像修改程序名称.拍照日期.拍照地点等.ImageSoure类包含ImageMetadata ...

  2. (转)原始图像数据和PDF中的图像数据

    比较原始图像数据和PDF中的图像数据,结果见表1.1.表1.1中各种“解码器”的解释见本文后续的“PDF支持的图像格式”部分,“PDF中的图像数据”各栏中的数据来自开源的PdfView.如果您有兴趣查 ...

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

    PPM图像格式介绍 PPM图像格式是由Jef Poskanzer 大叔,在我出生那一年,也就是1991年所创造的,碰巧的是PPM也是天蝎座. PPM(Portable Pixmap Format)还有 ...

  4. GPUImage相关(转)

    3.滤镜 除了上面提到的美颜和水印之外,视频中还有很多其它的处理效果也在这个环节完成.七牛直播云提供的 SDK 在开放性设计基础之上,通过数据源回调接口,可以支持各种自定义滤镜的接入. 为了实现丰富的 ...

  5. 基于DCMTK的DICOM相关程序编写攻略

    2008年09月10日 星期三 15:35 基于DCMTK的DICOM相关程序编写攻略 前言: 由于现在的医学影像设备的图像存储和传输正在逐渐向DICOM标准靠拢,在我们进行医学图像处理的过程中,经常 ...

  6. Labview实现脉波调制( PPM )

    Labview实现脉波调制( PPM ) 根据定义为脉冲宽度调制 生成一个正弦信号,得到其幅值输入给一个方波信号的偏移量 由于方波信号的偏移量里面含有正弦信号的信息 因此通过对方波信号的上升沿或下降沿 ...

  7. Android 多种方式正确的加载图像,有效避免oom

    图像加载的方式: Android开发中消耗内存较多一般都是在图像上面,本文就主要介绍怎样正确的展现图像减少对内存的开销,有效的避免oom现象.首先我们知道我的获取图像的来源一般有三种源头:1.从网络加 ...

  8. linux学习:特殊符号,数学运算,图像与数组与部分终端命令用法整理

    指令:let.expr.array.convert.tput.date.read.md5.ln.apt.系统信息 一:特殊符号用法整理 系统变量 $# 是传给脚本的参数个数 $0 是脚本本身的名字 $ ...

  9. Delphi实现图像文本旋转特效完整代码

    Delphi实现图像文本旋转特效完整代码,本程序利用的控件主要是Panel 控件.Image 控件.Edit 控件.Label 控件和Button 控件.本程序的关键是利用Delphi 的bmp_ro ...

随机推荐

  1. Linux——vi命令的使用

    vi的基本操作 a) 进入vi 在系统提示符号输入vi及文件名称后,就进入vi全屏幕编辑画面: $ vi myfile 不过有一点要特别注意,就是您进入vi之后,是处于「命令行模式(command m ...

  2. 【BIEE】10_资料库查看数据报错

    导入元数据后,在资料库右键物理表名,[查看数据]报错: 出现这个问题,没搞明白是为啥- 后来百度意外发现一个方法,修改NQSConfig.INI文件即可解决问题 那么就开始来搞定这个问题 [1]打开路 ...

  3. mongoDB 特别指令用法

    http://apluck.iteye.com/blog/1176160 a.   修改collection集合字段名 参见:http://www.mongodb.org/display/DOCS/U ...

  4. java检测http请求的ip地址 Java问题通用解决代码

    以后再用到的话,至少能起个参考作用 java实现,struts2的Action中,依赖HttpServletRequest     package net.dookoo.web.action;   i ...

  5. ios7中的edgesForExtendedLayout

    edgesForExtendedLayout是一个类型为UIExtendedEdge的属性,指定边缘要延伸的方向. 因为iOS7鼓励全屏布局,所以它的默认值是UIRectEdgeAll——四周边缘都延 ...

  6. FP Tree算法原理总结(转载)

    FP Tree算法原理总结 在Apriori算法原理总结中,我们对Apriori算法的原理做了总结.作为一个挖掘频繁项集的算法,Apriori算法需要多次扫描数据,I/O是很大的瓶颈.为了解决这个问题 ...

  7. 尽管是一个CS专业的学生,小B的数学基础很好并对数值计算有着特别的兴趣,喜欢用计算机程序来解决数学问题。现在,她正在玩一个数值变换的游戏。她发现计算机中经常用不同的进制表示同一个数,如十进制数123表达为16进制时只包含两位数7、11(B),用八进制表示时为三位数1、7、3。按不同进制表达时,各个位数的和也不同,如上述例子中十六进制和八进制中各位数的和分别是18和11。

    include "stdafx.h" #include<iostream> #include<vector> #include <algorithm& ...

  8. Redis源码阅读-Adlist双向链表

    Redis源码阅读-链表部分- 链表数据结构在Adlist.h   Adlist.c Redis的链表是双向链表,内部定义了一个迭代器. 双向链表的函数主要是链表创建.删除.节点插入.头插入.尾插入. ...

  9. 11 Memcached 缓存雪崩现象

    一:Memcached 缓存雪崩现象(1)造成原因:一般是由某个节点失效,导致其他的节点的缓存命中率下降,缓存中缺失的数据查询,短时间内造成的数据库服务器奔溃.重启DB,短期内又被压垮,但缓存的数据增 ...

  10. YUM安装(卸载)KDE和GNOME

    YUM安装(卸载)KDE和GNOME显示系统已经安装的组件,和可以安装的组件:#yum grouplist 如果系统安装之初采用最小化安装,没有安装xwindow,那么先安装:#yum groupin ...