文章目录

  • Chapter 1: 图片格式
    • PPM
      • 格式
      • C++代码实现
      • 输出
    • BMP
      • 格式
      • C++实现
      • 输出
    • JPEG/JPG
      • 格式

Chapter 1: 图片格式

PPM

PPM format: PPM格式是一种用于表示图像的文件格式,全称为“Portable Pixmap”,通常也简称为 PPM 图像。它是一种比较简单的图片格式,不需要压缩,也不受操作系统和软件平台的限制。

其文本形式一般为这样:

P3
200 100
255
0 223 45
1 223 45
2 223 45
3 223 45
4 223 45
5 223 45
6 223 45
7 223 45
9 223 45
... ...

格式

PPM文件的格式可以分为三个部分:头信息像素矩阵原始数据

  • 头信息部分是PPM文件的开头,以“P6”或“P3”开头表示彩色或灰度(颜色深度)图像,后面跟着一些描述图像的参数。具体格式如下:

    • P6(或P3) # 文件类型,P6表示二进制数据,P3表示ASCII码
      宽度 # 图像的宽度
      高度 # 图像的高度
      最大像素值 # 每个像素点颜色通道的最大值,通常是255
  • 像素矩阵部分是一个二维数组,存储了每个像素点的颜色信息。

    • 对于彩色图像,每个像素点需要存储红、绿、蓝三个通道的颜色值,因此每个像素点需要占据三个字节。

    • 对于黑白或灰度图像,每个像素点只需要存储一个通道的灰度值,因此每个像素点只需要占据一个字节。

    • 像素的存放顺序通常是从左到右,从上到下的顺序排列。

  • 原始数据部分包含了所有的像素信息,它表示的就是图像的真实内容。

  • 对于二进制文件,每个像素点的颜色信息以三个字节的形式存储(需要注意的是,在使用二进制格式存储PPM文件时,一个像素点的颜色信息可能会被分为多行存储,因此在读取数据时需要注意边界问题和字节对齐的问题);

  • 对于ASCII码文件,每个像素点的颜色信息以一个或多个数字组成的字符串形式存储,每个数值之间通常用空格、制表符或换行符隔开。

注:

颜色信息

其颜色信息通常是以 RGB 三原色模式来表达的,每个像素点包含一个红色通道、一个绿色通道和一个蓝色通道。像素矩阵是一个二维矩阵,存储了每个像素点的颜色值。

对于彩色图片,每个颜色通道都占据一个字节(8位),范围从0到255;

对于灰度图片,只有一个通道,一个像素点只占一个字节,范围同样从0到255。

最大像素值

当然,除了255之外也可以设置其他的最大值,例如 127、63、31 等其他的值 ( 2 n − 1 ) (2^n-1) (2n−1)。但是需要注意的是,选择不同的最大值将会影响到图像的质量和精度。如果最大值太小,将会导致图像的灰度级别较少,因此可能损失一部分细节信息;如果最大值太大,将会占用更多的空间,同时也可能会造成颜色通道之间的冗余数据。因此,在选择最大值时需要根据具体情况进行调整。

应用

PPM 格式的图像文件大小较大,因此在存储和传输方面相对不够便利,但是其简单、通用的特点使得在实际应用中,其常常作为中间格式和数据交换格式来使用,以便在不同的系统和软件之间进行图像数据的传输和转换。

C++代码实现

/*PPM example*/
int width = 200;
int heighth = 100;
cout << "P3" << "\n" << width << ' ' << heighth << "\n255\n";
for (int i = 0; i < width * heighth; i++)
{float intensity = (float)i /(float)(width * heighth);int red = (int)(intensity * 255);cout << red << ' ' << '0' << ' ' << '0' << endl;
}
cout << "done" << endl;

//或是可以反向
for (int i = width * heighth-1; i >= 0; i--)

输出

  1. 可以加入文件处理语句,再将文件后缀改为.ppm

其他样式:

//波纹状
for (int i = (width * heighth)/2; i >= 0; i--)
{float intensity = (float)i /(float)(width * heighth)/2;int bw = intensity*(width * heighth)/2;outfile << '0' << ' ' << bw << ' ' << '0' << endl;
}
for (int i = 0; i < (width * heighth) / 2; i++)
{float intensity = (float)i / (float)(width * heighth) / 2;int bw = intensity * (width * heighth) / 2;outfile << '0' << ' ' << bw << ' ' << '0' << endl;
}
//向外渐变
for (int i = width * heighth - 1; i >= 0; i--)
{float intensity = (float)i /(float)(width * heighth);int green = 255 - intensity * 512;if(green >= 0)outfile << '0' << ' ' << green << ' ' << '0' << endl;elseoutfile << '0' << ' ' << -green << ' ' << '0' << endl;
}


/*双色*/
for (int i = 0, j = width * heighth-1; i < width * heighth; i++, j--)
{float ir = (float)i / (float)(width * heighth);float ig = (float)j / (float)(width * heighth);int r = ir * 255;int g = ig * 255;int b = 100;outfile << r << ' ' << g << ' ' << b << endl;
}
/*三色*/
for (int j = ny - 1; j >= 0; j--)for (int i = 0; i < nx; i++){float r = float(i) / float(nx);float g = float(j) / float(ny);float b = g;int ir = int(225.99 * r);int ig = int(225.99 * g);int ib = int(225.99 * b);/*pixel matrix(array called better)*/outfile << ir << " " << ig << " " << ib << "\n";}


//灰度(当RGB相同时)
for (int i = 0; i < width * heighth; i++)
{float intensity = (float)i / (float)(width * heighth);int rgb = intensity * 255;outfile << rgb << ' ' << rgb << ' ' << rgb << endl;
}


BMP

BMP 格式是一种 Microsoft Windows 系统下广泛使用的图片格式,它的格式定义相对 PPM 更为复杂,支持的特性也更加丰富,例如存储有关于图像颜色空间(如 RGB 或 CMYK)的额外元数据。而 XBM 格式不支持颜色深度或者颜色空间的信息。

格式

BMP文件由文件头(BITMAPFILEHEADER)、图像信息头(BITMAPINFOHEADER)以及图像数据三个部分组成(与ppm差不多):

  • 文件头包括两个部分,共14个字节,用于标识该文件的类型和属性,并且出现在文件的开头位置。具体结构如下:
typedef struct tagBITMAPFILEHEADER {WORD bfType;     // 2 bytes,指明该文件为BMP文件,值固定为0x4D42(即"BM")DWORD bfSize;    // 4 bytes,指明该文件所占空间大小,单位字节WORD bfReserved1;// 2 bytes,保留,必须设置为0WORD bfReserved2;// 2 bytes,保留,必须设置为0DWORD bfOffBits; // 4 bytes,指明从文件头开始到图像数据区域的偏移量,单位字节
} BITMAPFILEHEADER;
  • 信息头记录了与该BMP文件相关的关键性信息,包含40个字节,可以分为不同种类,主要有BITMAPCOREHEADER、BITMAPINFOHEADER、BITMAPV2INFOHEADER、BITMAPV3INFOHEADER、BITMAPV4HEADER和BITMAPV5HEADER等,其中最常用的是BITMAPINFOHEADER,其结构体如下:
typedef struct tagBITMAPINFOHEADER {DWORD biSize;          // 4 bytes,指明该信息头的大小LONG biWidth;          // 4 bytes,指明图像的宽度,单位像素LONG biHeight;         // 4 bytes,指明图像的高度,单位像素WORD biPlanes;         // 2 bytes,用于指定目标设备的平面数,必须为1WORD biBitCount;       // 2 bytes,指明每个像素占用的位数(即颜色深度)DWORD biCompression;   // 4 bytes,指明图像数据的压缩方式DWORD biSizeImage;     // 4 bytes,指明图像数据的大小,单位字节LONG biXPelsPerMeter;  // 4 bytes,指明水平分辨率,单位像素/米LONG biYPelsPerMeter;  // 4 bytes,指明垂直分辨率,单位像素/米DWORD biClrUsed;       // 4 bytes,指明调色板中实际使用的颜色数DWORD biClrImportant;  // 4 bytes,指明被认为是重要颜色的索引数
} BITMAPINFOHEADER;
  • 颜色表
    BMP文件支持使用颜色表来记录图像色彩信息,存储在文件中的调色板表可以由BI_RGB标志指定的24位和32位格式省略

  • 位图数据区
    BMP文件的最后部分就是实际的位图数据,如同名字所示,该区域包含了图像中每个像素的颜色信息。在不压缩的BMP文件中,每一个像素都与调色板中的一个颜色对应,若采用24位或32位真彩色,则将RGB或RGBA等颜色直接编码到图像数据中。

BMP文件格式文件大小相对较大,通常适合于需要保留图像精度的场合,而因为历史和技术原因,其一些参数的取值也相对随意,因此在解析时需要注意读取方式和对错误值的处理。

C++实现

#include <iostream>
#include <fstream>using namespace std;#pragma pack(push, 1) // 设置按照字节对齐
struct BMPHeader {char header_field1[2] {'B', 'M'}; // BMP 文件头标识uint32_t file_size; // 文件大小,4 个字节uint16_t reserved1 {0}; // 保留字段,2 个字节uint16_t reserved2 {0}; // 保留字段,2 个字节uint32_t pixel_data_offset; // 像素数据起始位置,从文件头开始计算的偏移量,4 个字节uint32_t dib_header_size {40}; // DIB 头大小,4 个字节int32_t width; // 图像宽度,4 个字节int32_t height; // 图像高度,4 个字节uint16_t planes {1}; // 位平面数,设定为 1,2 个字节uint16_t bits_per_pixel {24}; // 每个像素的位数,3 byte,24 位uint32_t compression {0}; // 压缩类型,BI_RGB 表示无压缩,4 个字节uint32_t size_of_bitmap {0}; // 图像大小,以字节为单位,BI_RGB 模式下可以设置为 0,4 个字节int32_t horizontal_resolution {2835}; // 水平分辨率,像素/米,很随意int32_t vertical_resolution {2835}; // 垂直分辨率,像素/米,很随意uint32_t colors_used {0}; // 颜色表中实际使用的颜色数,BI_RGB 模式下可以设置为 0,4 个字节uint32_t important_colors {0}; // 指定重要的颜色数,BI_RGB 模式下可以设置为 0,4 个字节
};
#pragma pack(pop)int main()
{int nx = 200;int ny = 100;const int row_size = ((nx * 3 + 3) / 4) * 4; // BMP 中每行像素数据必须是 4 的倍数,对于 24 位像素数据,每个像素占用 3 byteconst int pixel_data_size = row_size * ny; // 计算像素数据总大小const int file_size = sizeof(BMPHeader) + pixel_data_size; // 计算文件总大小BMPHeader bmp_header;bmp_header.file_size = file_size;bmp_header.pixel_data_offset = sizeof(BMPHeader); // BMP 文件头和 DIB 头共计 54 bytesbmp_header.width = nx;bmp_header.height = ny;ofstream outfile("mytest.bmp", ios_base::out | ios_base::binary);outfile.write(reinterpret_cast<const char*>(&bmp_header), sizeof(BMPHeader));std::cout << "P3\n" << nx << " " << ny << "\n255\n";for (int j = ny - 1; j >= 0; j--){for (int i = 0; i < nx; i++){float r = float(i) / float(nx);float g = float(j) / float(ny);float b = 0.2;int ir = int(255.99 * r);int ig = int(255.99 * g);int ib = int(255.99 * b);outfile.put(static_cast<char>(ib));outfile.put(static_cast<char>(ig));outfile.put(static_cast<char>(ir));std::cout << ir << " " << ig << " " << ib << "\n";}for (int k = 0; k < row_size - nx * 3; k++) {outfile.put(static_cast<char>(0)); // 填充到 4 的倍数}}
}

输出


JPEG/JPG

JPEG/JPG是一种有损的压缩图像格式,采用了离散余弦变换(DCT)和量化的技术来压缩图像数据。

格式

  • 文件头
    JPG文件的文件头共2个字节,用于标识该文件的类型和属性。其中第一个字节的值为0xFF,表示这是一个JPG文件,第二个字节决定了接下来的数据类型。

  • 图像信息
    JPG的图像信息包括两类数据:应用数据段(APPn,n=0f)和标记数据段(Mk,k=0f)。

  • 应用数据段:包含了与该图像相关的应用程序的信息,例如照片拍摄时间、设备制造商等。
    标记数据段:包含了该图像的压缩信息、分量数、每个分量的采样精度以及哈夫曼表(Huffman Table)等信息。其中,哈夫曼表记录了JPG压缩算法中使用的编码表,用于将图像的像素值编码为二进制数据。

  • 量化表
    JPG使用量化表对图像进行有损压缩,用于降低图像数据冗余和噪声的影响,从而减小图像文件的大小。

  • 帧数据
    JPG采用基于YCbCr颜色空间的色彩模型,将图像分解为亮度(Y)和色度(Cb和Cr)三个分量,并将每个分量进行离散余弦变换和量化处理。帧数据段包括了压缩后的亮度和色度数据以及采样率等信息。

  • 扫描数据
    扫描数据段是JPG文件中最重要的部分,它包含了压缩后的图像数据。在该数据段中,采用了游程编码(Run-length Coding)和哈夫曼编码(Huffman Coding)等算法对图像数据进行压缩和编码,在遍历过程中根据哈夫曼表解码并还原出图像数据。

JPG是一种高效的图像压缩格式,具有良好的压缩比和图像质量。但它也是一种有损压缩格式,会丢失一部分图像信息,因此适合于在保证图像质量的前提下尽可能地减小文件大小

计算机图形学【1】基础概念,图片格式及C++实现相关推荐

  1. Games101计算机图形学入门基础之二:光栅化

    Games101计算机图形学入门基础之二:光栅化 引言 三角形的离散化 采样 走样 走样带来的瑕疵 反走样 先模糊再采样 傅里叶变换 低通滤波 卷积 多重采样抗锯齿(超采样) 深度缓存 可见性与遮挡( ...

  2. Games101计算机图形学入门基础之一:向量变换、矩阵变换、视图变换、欧拉角与四元数

    Games101计算机图形学入门基础之一:向量变换.矩阵变换.齐次坐标.欧拉角与四元数 目录 Games101计算机图形学入门基础之一:向量变换.矩阵变换.齐次坐标.欧拉角与四元数 前言 向量 向量加 ...

  3. 计算机图形学应用基础考试,计算机图形学基础期末考试试题.docx

    计算机图形学基础期末考试试 题 一. 填空 1.将多 形外部一点 A 与某一点 B 用 段 接,若此 段与多 形 界相交的次数 ??????????, 点 B在多 形外部.若此 段与多 形 界相交的次 ...

  4. 计算机图形数学知识,平面----计算机图形学的基础几何知识

    平面在数学上的定义是,平面,是指面上任意两点的连线整个落在此面上. 在现实生活中你很容易一眼看出什么平面,但是在计算机的程序里,你将如何表示一个平面的呢? 又是怎么样求点到平面的距离? 判断点在平面的 ...

  5. 【计算机图形学】基础 - Colorization using Optimization

    这里写目录标题 1. 已存在的问题 2. 文章目标 3. 文章算法 3.1 文章相关定义与所需知识 3.2 算法 3.3 方程的求解 4. 文章贡献 5. 代码实现 5.1 环境配置 5.2 代码实现 ...

  6. 计算机图形学消隐的概念

    要真实显示三维物体,必须在视点确定之后,将对象表面上不可见的点.线.面消去:执行这种功能的算法称为消隐算法.根据消隐对象的不同,分为:线消隐,面消隐.     因为在计算机图形处理的过程中,不会自动消 ...

  7. 【OpenGL】计算机图形学OpenGL基础

    前面几节是跟着B站视频学习的OpenGL基础操作,算是熟悉了一下环境,下面进入学习opengl中文教程网站,开始真正进入OpenGL的大门. 下面开始学习计算机图形编程,收获自己做出很酷的东西的喜悦. ...

  8. 平面----计算机图形学的基础几何知识

    平面在数学上的定义是,平面,是指面上任意两点的连线整个落在此面上. 在现实生活中你很容易一眼看出什么平面,但是在计算机的程序里,你将如何表示一个平面的呢? 又是怎么样求点到平面的距离? 判断点在平面的 ...

  9. 计算机图形图像学基础,计算机图形学基础(第2版)

    计算机图形学基础(第2版) 语音 编辑 锁定 讨论 上传视频 <计算机图形学基础(第2版)>是2011年电子工业出版社出版的图书,作者是陆枫.何云峰. 书    名 计算机图形学基础(第2 ...

  10. 计算机图形学基础及应用大纲,《计算机图形学》教学大纲

    <计算机图形学>教学大纲 课程编号:1504P1113课程类型:专业选修 课程名称:计算机图形学 英文名称:Computer Graphics 学 分:2.5适用专业:信息与计算科学 一. ...

最新文章

  1. 一次哔哩哔哩面试经历,真香!
  2. 024_jdbc-mysql的Dao模式
  3. 消费流程图_SpringBoot+RabbitMQ ,保证消息100%投递成功并被消费(附源码)
  4. WinForm - 两个窗体之间的方法调用
  5. 全国计算机等级考试用报名吗,全国计算机等级考试网上报名流程及考生报名使用说明...
  6. 近代数字信号处理实验-DFT分析信号的频谱
  7. IDEA生成可运行jar包
  8. Spark Scalaa 几个常用的示例
  9. PyQt5, PushButton
  10. sqlite工作记录-1数据库数据写入-转
  11. 详细解说STL string
  12. apk html启动图,apk添加启动图(AddApkSplashTools)
  13. sql 插入日期格式
  14. 如何导入JDBC驱动
  15. android bmob获取密码,Bmob后端云初体验
  16. Warshall沃舍尔算法
  17. vue提交表单数据到后端
  18. 智能卷发器的原理和功能
  19. 拆解USB无线网卡,电路方案非常经典(附高清美图)
  20. Spring AOP 学习笔记

热门文章

  1. Android13 使用WindowManager ActivityEmbedding平行视窗
  2. 缓存相关问题总结-1
  3. bzoj1897. tank 坦克游戏(决策单调性分治)
  4. 阿里云Redis之:配置程序接入阿里云Redis集群缓存数据(十七)
  5. 蓝屏代码critical process died如何修复?
  6. Scrapy实现对新浪微博某关键词的爬取以及不同url中重复内容的过滤
  7. puzzle拼图(puzzle拼图9级答案)
  8. 稀疏(sparsity)矩阵的行压缩存储
  9. 数据结构与算法实验题7.2 连环计
  10. Win10 新装系统Maya安装失败原因