图像处理与Linux编程基础
2026/7/23 12:42:46 网站建设 项目流程

目录

  • 一、BMP图像
    • 1. 文件整体结构
    • 2. 位图头文件数据结构
    • 3. 位图信息数据结构
    • 4. 调色板
    • 5. 位图数据
    • 6. 要点
  • 二、JPEG图像
    • 1. 文件格式
    • 2. 标记定义
  • 三、YUV图像
    • 1. 文件结构
    • 2. 转换公式与要点
  • 四、图像缩放
  • 五、makefile编写
  • 六、Linux多线程编程
    • 1. 线程的概念
    • 2. POSIX线程
    • 3. 几个最基本的库函数
    • 4. 编译要点
  • 七、信号量
  • 八、进程间通信
    • 1. 命名管道:FIFO
      • 命名管道的创建
      • 命名管道的访问

一、BMP图像

1. 文件整体结构

典型的BMP图像文件由四部分组成:

  1. 位图头文件数据结构:包含BMP图像文件的类型、显示内容等信息;
  2. 位图信息数据结构:包含BMP图像的宽、高、压缩方法,以及定义颜色等信息;
  3. 调色板:可选部分,有些位图需要调色板,有些位图(如真彩色图24位的BMP)不需要调色板;
  4. 位图数据:根据BMP位图使用的位数不同而不同,24位图中直接使用RGB,其他小于24位的使用调色板中颜色索引值。

2. 位图头文件数据结构

共14字节,含有BMP文件的类型、文件大小和位图起始位置等信息,结构体声明如下:

typedefstructtagBITMAPFILEHEADER{ushort u16bfType;// 位图文件的类型,必须为BM(1-2字节)uint u32bfSize;// 位图文件的大小,以字节为单位(3-6字节,低位在前)ushort u16bfReserved1;// 位图文件保留字,必须为0(7-8字节)ushort u16bfReserved2;// 位图文件保留字,必须为0(9-10字节)uint u32bfOffBits;// 位图数据的起始位置,以相对于位图(11-14字节,低位在前)}__attribute__((packed))BITMAPFILEHEADER;

3. 位图信息数据结构

共40字节,用于说明位图的尺寸等信息,结构体声明如下:

typedefstructtagBITMAPINFOHEADER{uint u32biSize;// 本结构所占用字节数(15-18字节)uint u32biWidth;// 位图的宽度,以像素为单位(19-22字节)uint u32biHeight;// 位图的高度,以像素为单位(23-26字节)ushort u16biPlanes;// 目标设备的级别,必须为1(27-28字节)ushort u16biBitCount;// 每个像素所需的位数,必须是1(双色)、4(16色)、8(256色)、16(高彩色)或24(真彩色)之一(29-30字节)uint u32biCompression;// 位图压缩类型,必须是0(不压缩)、1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一(31-34字节)uint u32biSizeImage;// 位图的大小,以字节为单位,其中包含了为了补齐行数是4的倍数而添加的空字节(35-38字节)uint u32biXPelsPerMeter;// 位图水平分辨率,每米像素数(39-42字节)uint u32biYPelsPerMeter;// 位图垂直分辨率,每米像素数(43-46字节)uint u32biClrUsed;// 位图实际使用的颜色表中的颜色数(47-50字节)uint u32biClrImportant;// 位图显示过程中重要的颜色数(51-54字节)}__attribute__((packed))BITMAPINFOHEADER;

4. 调色板

用于说明位图中的颜色,有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下:

typedefstructtagRGBQUAD{uchar u8rgbBlue;// 蓝色的亮度(值范围为0-255)uchar u8rgbGreen;// 绿色的亮度(值范围为0-255)uchar u8rgbRed;// 红色的亮度(值范围为0-255)uchar u8rgbReserved;// 保留,必须为0}__attribute__((packed))RGBQUAD;

颜色表中RGBQUAD结构数据的个数由biBitCount来确定:

  • biBitCount=1时,有2个表项
  • biBitCount=4时,有16个表项
  • biBitCount=8时,有256个表项
  • biBitCount=24时,没有颜色表项

位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:

typedefstructtagBITMAPINFO{BITMAPINFOHEADER bmiHeader;// 位图信息头RGBQUAD bmiColors[1];// 颜色表}__attribute__((packed))BITMAPINFO;

5. 位图数据

位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:

  • biBitCount=1时,8个像素占1个字节
  • biBitCount=4时,2个像素占1个字节
  • biBitCount=8时,1个像素占1个字节
  • biBitCount=24时,1个像素占3个字节,按顺序分别为B、G、R

结构体声明如下:

typedefstruct{uchar u8b;uchar u8g;uchar u8r;}RGB;

6. 要点

由于编译器存在着字节自动对齐的问题,声明结构体的时候需要添加__attribute__((packed))让编译器取消自动对齐,才会获得正确的大小。

使用__attribute__((packed))

typedefstructtagBITMAPFILEHEADER{ushort u16bfType;// 位图文件的类型,必须为BM(1-2字节)uint u32bfSize;// 位图文件的大小,以字节为单位(3-6字节,低位在前)ushort u16bfReserved1;// 位图文件保留字,必须为0(7-8字节)ushort u16bfReserved2;// 位图文件保留字,必须为0(9-10字节)uint u32bfOffBits;// 位图数据的起始位置,以相对于位图(11-14字节,低位在前)}__attribute__((packed))BITMAPFILEHEADER;// sizeof(BITMAPFILEHEADER) = 14

不使用__attribute__((packed))

typedefstructtagBITMAPFILEHEADER{ushort u16bfType;// 位图文件的类型,必须为BM(1-2字节)uint u32bfSize;// 位图文件的大小,以字节为单位(3-6字节,低位在前)ushort u16bfReserved1;// 位图文件保留字,必须为0(7-8字节)ushort u16bfReserved2;// 位图文件保留字,必须为0(9-10字节)uint u32bfOffBits;// 位图数据的起始位置,以相对于位图(11-14字节,低位在前)}BITMAPFILEHEADER;// sizeof(BITMAPFILEHEADER) = 16

二、JPEG图像

1. 文件格式

JPEG文件由下面的8个部分组成:

(1) 图像开始 SOI (Start of Image) 标记
  • 标记代码:2字节,固定值0xFFD8
(2) APP0 标记 (Marker)
  • 标记代码:2字节,固定值0xFFE0
  • 字段说明
    1. APP0长度 (length):2字节,①~⑨9个字段的总长度
    2. 标识符 (identifier):5字节,固定值0x4A46494600,即字符串"JFIF0"
    3. 版本号 (version):2字节,一般是0x0102,表示JFIF的版本号1.2
    4. X和Y的密度单位 (units):1字节,0:无单位;1:点数/英寸;2:点数/厘米
    5. X方向像素密度 (X density):2字节
    6. Y方向像素密度 (Y density):2字节
    7. 缩略图水平像素数目 (thumbnail horizontal pixels):1字节
    8. 缩略图垂直像素数目 (thumbnail vertical pixels):1字节
    9. 缩略图RGB位图 (thumbnail RGB bitmap)

标记段⑨可以包含图像的一个微缩版本,存为24位的RGB像素。如果没有微缩图像(这种情况更常见),则字段⑦和字段⑧的值均为0。

(3) APPn 标记 (Markers),其中 n=1~15 (任选)
  • 标记代码:2字节,固定值0xFFE1~0xFFEF
  • 字段说明
    1. APPn长度 (length):2字节,①~②2个字段的总长度
    2. 详细信息 (application specific information):(数据长度-2)字节,内容不定

例如,Adobe Photoshop生成的JPEG图像中就用了APP1和APP13两个标记段分别存储了一幅图像的副本;Exif将数码照片的拍摄参数、缩略图及其他属性信息记录在APP1中。值得注意的是,同一APPn标记可以同时出现多个,例如用Ps处理过的数码相机拍摄的照片,可能会存在2个APP1标记。

(4) 一个或者多个量化表 DQT (Define Quantization Table)
  • 标记代码:2字节,固定值0xFFDB,最多只能出现4次
  • 字段说明
    1. 量化表长度 (quantization table length):2字节,①~③三个字段的总长度
    2. 量化表号 (quantization table number):1字节
    3. 量化表 (quantization table)

另一种说法为:

  • 精度及量化表ID:1字节,高4位:精度,0:8位;1:16位,低4位:量化表ID,取值范围为0~3
  • 表项:64×(精度+1)字节,例如8位精度的量化表,其表项长度为64×(0+1)=64字节

查不到更多资料,无法分辨哪一种是正确的。

(5) 帧图像开始 SOF0 (Start of Frame)
  • 标记代码:2字节,固定值0xFFC0
  • 字段说明
    1. 帧开始长度 (start of frame length):2字节,①~⑥六个字段的总长度
    2. 精度 (precision):1字节,每个颜色分量每个像素的位数,通常是8位
    3. 图像高度 (image height):2字节,图像高度(单位:像素),如果不支持DNL就必须>0
    4. 图像宽度 (image width):2字节,图像宽度(单位:像素),如果不支持DNL就必须>0
    5. 颜色分量数 (number of color components):1字节,1:灰度图;3:YCrCb或YIQ;4:CMYK。JFIF中使用YCrCb,故这里颜色分量数恒为3
    6. 对每个颜色分量 (for each component):颜色分量数×3字节(通常为9字节)
    • ID:1字节
    • 水平/垂直采样因子:1字节,高4位:水平采样因子,低4位:垂直采样因子
    • 量化表号 (quantization table#):1字节

字段⑥应该重复出现,有多少个颜色分量(字段⑤),就出现多少次(一般为3次)。

(6) 一个或者多个霍夫曼表 DHT (Define Huffman Table)
  • 标记代码:2字节,固定值0xFFC4
  • 字段说明
    1. 霍夫曼表的长度 (Huffman table length)
    2. 类型、AC或者DC (Type, AC or DC)
    3. 索引 (Index)
    4. 位表 (bits table)
    5. 值表 (value table)

DC表和AC表分开编码。另一种说法为:表ID和表类型占1字节,高4位:类型,0:DC直流;1:AC交流;低4位:哈夫曼表ID。

由于查不到更多资料,无法得出详细含义。

(7) 扫描开始 SOS (Start of Scan)
  • 标记代码:2字节,固定值0xFFDA
  • 字段说明
    1. 扫描开始长度 (start of scan length):2字节,①~④两个字段的总长度
    2. 颜色分量数 (number of color components):1字节,应该和SOF中的字段⑤的值相同,1:灰度图;3:YCrCb或YIQ;4:CMYK
    3. 每个颜色分量
    • ID:1字节
    • 直流/交流系数表号:1字节,高4位:直流分量使用的哈夫曼树编号,低4位:交流分量使用的哈夫曼树编号
    1. 压缩图像数据 (compressed image data)
    • 谱选择开始:1字节,固定值0x00
    • 谱选择结束:1字节,固定值0x3F
    • 谱选择:1字节,在基本JPEG中总为00

字段③应该重复出现,有多少个颜色分量(字段②),就出现多少次(一般为3次)。

本段结束后,紧接着就是真正的图像信息了。图像信息直至遇到一个标记代码就自动结束,一般就是以EOI标记表示结束。

(8) 图像结束 EOI (End of Image)
  • 标记代码:2字节,固定值0xFFD9
其他可能出现的标记段

DRI (Define Restart Interval):定义差分编码累计复位的间隔

  • 标记代码:2字节,固定值0xFFDD
  • 包含2个具体字段
    1. 数据长度:2字节,固定值0x0004,①~②两个字段的总长度
    2. MCU块的单元中的重新开始间隔:2字节,设其值为n,则表示每n个MCU块就有一个RSTn标记。第一个标记是RST0,第二个是RST1等,RST7后再从RST0重复

如果没有本标记段,或间隔值为0时,就表示不存在重开始间隔和标记RST。

2. 标记定义

如果在图像数据流中遇到0xFF,应该检测其紧接着的字符:

  • 0x00:表示0xFF是图像流的组成部分,需要进行译码
  • 0xD0~0xD7:组成RSTn标记,则忽视整个RSTn标记,即不对当前0xFF和紧接的0xDn两个字节进行译码,并按RST标记的规则调整译码变量
  • 0xFF:忽视当前0xFF,对后一个0xFF再作判断
  • 其他数值:忽视当前0xFF,并保留紧接的此数值用于译码
符号标记代码说明英文解释原文
起始帧标记,非分层霍夫曼编码Start Of Frame markers, non-hierarchical Huffman coding
SOF00xFFC0基线DCTBaseline DCT
SOF10xFFC1扩展顺序DCTExtended sequential DCT
SOF20xFFC2逐行DCTProgressive DCT
SOF30xFFC3空间(顺序)无损Spatial (sequential) lossless
起始帧标记,分层霍夫曼编码Start Of Frame markers, hierarchical Huffman coding
SOF50xFFC5差分顺序DCTDifferential sequential DCT
SOF60xFFC6差分渐进DCTDifferential progressive DCT
SOF70xFFC7差分空间无损Differential spatial lossless
起始帧标记,非分层算术编码

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询