- 浏览: 362784 次
文章分类
最新评论
-
lord_is_layuping:
...
PYQT4 + Python2.6 + eric4-4.2.2a的安装全过程 -
597272095:
3Q
Oracle客户端PL/SQL 中文乱码解决 -
lpluck08:
如果不是在git本地版本目录中执行的话,会有问题。到本地版本目 ...
git 中文文件名 乱码 mac -
aiove:
-API
分享到: 阿撒旦发撒旦发速度飞洒发
iOS开发开源项目推荐 -
Wallian_hua:
感谢,楼主的详细分析,对我的启发很大。。我也正在研究这方面的技 ...
[ZT]简单OCR实现原理
摘要:
这篇文章大体上介绍了 JPEG 文件的结构信息以及它的压缩算法和编码方式。使读者能够对 JPEG 文件格式有大体上的了解。为读者进一步进行学习 JPEG 文件压缩做好准备
关键字: 十六进制,段格式,编码
一、 JPEG文件格式概述:
图像和动画的存储方式是一个很重要的问题。幸好我们有了数据压缩,有了 JPEG 等多种压缩存储图像的文件格式,我们今天才能够拿着小小的一个存储器,却存上许多张色彩鲜艳的图片。如果没有图像压缩算法,也许我们的多媒体时代就会晚到来许多年。
JPEG 图像存储格式一个比较成熟的图像有损压缩格式,虽然一个图片经过转化为 JPEG 图像后,一些数据会丢失,但是,人眼是很不容易分辨出来这种差别的。也就是说, JPEG 图像存储格式既满足了人眼对色彩和分辨率的要求,又适当的去除了图像中很难被人眼所分辨出的色彩,在图像的清晰与大小中 JPEG 找到了一个很好的平衡点。
虽然图像转化为 JPEG 格式会减小很多,但是并不是文件就变得简单了,相反, JPEG 文件的格式是比较复杂的。不经过认真地分析,是不容易弄懂它的。
二、 JPEG文件的存储方式:
JPEG 文件的格式是分为一个一个的段来存储的(但并不是全部都是段),段的多少和长度并不是一定的。只要包含了足够的信息,该 JPEG 文件就能够被打开,呈现给人们。 JPEG 文件的每个段都一定包含两部分一个是段的标识,它由两个字节构成:第一个字节是十六进制 0xFF ,第二个字节对于不同的段,这个值是不同的。紧接着的两个字节存放的是这个段的长度(除了前面的两个字节 0xFF 和 0xXX , X 表示不确定。他们是不算到段的长度中的)。注意:这个长度的表示方法是按照高位在前,低位在后的,与 Intel 的表示方法不同。比方说一个段的长度是 0x12AB ,那么它会按照 0x12 , 0xAB 的顺序存储。但是如果按照 Intel 的方式:高位在后,低位在前的方式会存储成 0xAB , 0x12 ,而这样的存储方法对于 JPEG 是不对的。这样的话如果一个程序不认识 JPEG 文件某个段,它就可以读取后两个字节,得到这个段的长度,并跳过忽略它。
本人曾经编写过一个读取 JPEG 文件信息的程序,该程序能够读取 JPEG 文件中包含的段的信息并显示出来。下面是一个 JPEG 图片的信息片断:
SOI
APP0 Length: 0x10
DQT
DQT [0]:
8 6 5 8 12 20 26 31
6 6 7 10 13 29 30 28
7 7 8 12 20 29 35 60
7 9 11 15 26 44 50 31
9 11 19 28 34 56 52 0
12 18 28 32 61 52 0 46
25 32 39 57 52 0 60 0
36 46 39 49 253 50 0 50
Length: 0x43
DQT
DQT [1]:
9 9 12 24 50 50 50 50
9 11 13 33 50 50 50 50
12 13 28 50 50 50 50 50
24 33 50 50 50 50 50 50
50 50 50 50 50 50 50 0
50 50 50 50 50 50 0 50
50 50 50 50 50 0 50 0
50 50 50 50 253 50 0 50
Length: 0x43
SOF0
Image Height: 173
Image Width: 401
Number of Frame(s): 3
****************
Content ID: 1
H Factor: 2
V Factor: 2
QT ID: 0
****************
Content ID: 2
H Factor: 1
V Factor: 1
QT ID: 1
****************
Content ID: 3
H Factor: 1
V Factor: 1
QT ID: 1
Length: 0x11
DHT
Type: DC TABLE
ID: 0
Length: 0x1f
DHT
Type: AC TABLE
ID: 0
Length: 0xb5
DHT
Type: DC TABLE
ID: 1
Length: 0x1f
DHT
Type: AC TABLE
ID: 1
Length: 0xb5
SOS Length: 0xc <-Will Not Process This Seg.
FATAL ERROR: File Structure Does NOT Support.
你首先会想到为什么最后会出现一个错误的信息呢?这是因为,在 SOS ( Start Of Scan )段的后面,就是编码后的一行一行的图像信息。不再是段的结构了。在开始的 SOI ( Start Of Image )不是一个段,它是文件的开始,它的值也是类似于 0xFF , 0xXX 的结构( SOI 的具体数值清自己察看相关书籍,本文章中将不作重点介绍),但是后面没有段的长度。在文件的最后,有一个 EOI ( End Of Image )的标识,它的结构和 SOI 是类似的。它标志着文件的结束。
在这中间,包含了 APP0 段, DQT 段, SOF0 段, DHT 段, SOS 段。有的段的个数是不唯一的,比方说 DQT 段。我们现在重点地介绍各个段的作用。
三、 JPEG文件中段的介绍:
APP0 段中主要存储的是图片的识别信息(字符串 ”JFIF\0” )、一些分辨率的信息以及缩略图的信息。在我的实际测试中,发现并不是所有的 JPEG 文件都有 APP0 段的,有的仅是有 APP2 之类的其他段,但是每个文件中肯定是包含 APPX 的段( X 可以取得的值可以查阅相关文档)。我个人估计,这些 APPX 的段的信息应该是大同小异。这个的验证还有待本人进一步的学习,目前只能说到这里。
DQT 段的内容是量化表的信息。众所周知,一个颜色可以分为 RGB (红、绿、兰)三个分量,这三色光组成了我们可以见到的所有色彩。但是,在 JPEG 文件中, RGB 色彩格式需要先转化为 YUV 的格式。 Y 分量代表了亮度信息, UV 分量代表了色差信息。相比之下,人眼对于 Y 分量更为敏感。量化表的作用就是对于一些不需要的量进行去除,这也是 JPEG 有损压缩损失数据的关键。上面的输出可以看到两个量化表,一个给 Y 分量,另一个给 UV 分量。其实,他们也可以共用一个量化表。一个量化的结果如下所示(摘自《 JPEG 压缩编码标准》):
15 0 -1 0 0 0 0 0
-2 -1 0 0 0 0 0 0
-1 -1 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
我们可以看到,量化后出现了大量的 0 ,这种结果很有利于我们进行下一步的数据压缩的。至于为什么是 8x8 的大小,待会你就知道了。
SOF0 段的内容是图像的大小信息,每个像素的位数信息,以及 YUV 每个分量分别得的采样信息(这部分如果读者想要进一步学习,请参考相应书籍和文档)。 JPEG 文件图像的编码是一个方块一个方块进行的,每块的大小为 8x8 大小(如果图像不是整数个方块的大小那么就对图像补齐为整数个大小)。简略地说采样信息,就是如何按组记录 YUV 的信息,即若干个 Y 方块,若干个 U 方块,若干个 V 方块经过量化的数据再次经过编码后组成一组记录,保存在 SOS 段结束后。
DHT 段的内容是一个重头戏,如果没有它, JPEG 压缩效率就不会那么高了。它内部定义的是一个 Huffman 表,不同的 DHT 段定义不同的 Huffman 表,有的是直流量的表,有的是交流量的表。什么是直流量,什么是交流量呢?待会我再作介绍。最多的 Huffman 表示几个呢? YUV 各一个,直流交流各一个,因为 YUV 每个分量都有直流和交流,所以最多时, Huffman 表有 3x2 个,也就是可以有 6 个 DHT 段。该文件中有 4 个 DHT 表,您可以大概猜出来是哪几个表么? Y 的直流和交流各一个 Huffman 表, UV 和起来直流和交流各一个 Huffman 表。这样说应该比较合理吧。
好了,现在我们应该弄明白什么是交流量,什么是直流量了。还举上面那个有许多个 0 的 8x8 的表的例子说,所谓交流量,是经过量化后的块内部除了左上角 15 那个值的其余值。实际上,块与块之间左上角那个值是用直流 Huffman 表来单独编码的。不与块内部一同编码。虽然不同的编码,但是要注意的事,不同的编码方式并不意味着它们是不在一起的,具体的存储编码后的数据的时候,还是按照若干个 Y 方块,若干个 U 方块,若干个 V 方块经过量化的数据再次经过编码后组成一组记录来存储的。
SOS 段的内容是关于 YUV 每个分量的直流和交流各使用那个 Huffman 表来编码的。
四、 JPEG文件十六进制代码解析
我觉得,如果想要的了解 JPEG ,对十六进制代码的观察是必不可少的。不要认为这样有多难,我会让你知道这是很简单的。目前我们只需要了解我们能够了解的东西就可以了。要记住,每个段的开始是 0xFF , 0xXX ,紧接着两个字节是长度信息。
可以看到,上图被选定的标记是 SOI 标记。
上图被选定的段是 APP0 段。
紧接着的段是 DQT 段,这个 JPEG 文件有两个 DQT 段。这里需要强调一点的是,包括量化表在内 8x8 的块的值是按照 Z 形来保存量化表 8x8 的数据的。而不是按照一行一行的保存的。这样做的好处是,能够让实际上相邻的像素点保存后也排列得比较近,便于压缩和编码。如下图所示:
(摘自《 JPEG 压缩编码标准》)
上图标记的段是 DHT 段,一共有 4 个 DHT 段。
这个段是 SOS 段,在这个段的后面就是所有压缩后的数据。
每段的具体信息在这里我就不详细介绍了,网上有很多相关的文章,如果有兴趣的话,可以去查找阅读。
五、 图像数据块内的编码方式
其实,图像数据块的编码是比较麻烦的,它涉及到了行程编码, Huffman 编码等编码方式。这部分很多文档说得都不是很清楚,我力求去除内部比较麻烦的部分,再通过简单的语言让大家明白原理,这样大家如果有兴趣进行下一步的研究,也会比较容易上手的。
我们还是使用那刚才那个包含很多 0 的量化后的 8x8 的数据块来说明。我们把块内剩余的 63 个数据用行程编码来编码。经过行程编码后的数据的格式是:( x,y )。 x 表示的是从当前位置开始有多少个连续的零, y 表示这些连续的 0 的后面的第一个非零的数是多少。但是为了解决存储的问题和进行进一步的压缩。最后的压缩格式变为:( x,y ) z 。 xy 占有一个字节的长度。 z 的长度不固定,需要根据 y 的值来判断。 x 仍代表从当前位置开始有几个连续的零,但是因为 x 只能占有四位的长度,也就是它的最大值是 15 ,所以,当多于 16 个连续的零的时候。会用一个字节的 (15,0) 来代替前面的 16 个 0 ,然后继续编码(注意:这时候没有 z 部分)。当块结束或者当前块后面剩余的都是零的时候,就用( 0,0 )即 EOB 代替(同样也是没有 z 部分)。前面说到 z 的长度不固定,需要根据 y 的值来判断,这是为什么呢?简单的来说, z 的长度是不一定的,在 1~15 的范围内。 Y 的作用简单的来说表示的是 z 的二进制位数( 1~15 ),也正好是 4 位二进制的值能够表示的。然后,把 xy 合成的一个字节单独提取出来,利用 DHT 里面的 Huffman 表来进行编码。这样,编码的长度又能够被压缩了。
六、 总结
叙述了这么多,相信大家对于 JPEG 已经有了一个大概的了解了吧,如果你通过阅读这篇文章,对 JPEG 文件的结构和算法有了一个大体上的认识,那么这篇文章的目的也就达到了。下一步进行具体研究就不会有太大问题了。祝愿大家能够在数据压缩的路上走好。
附件是jpeg 压缩标准
给出参考link http://www.jpeg.org/jpeg/index.html
- jpg.rar (77 KB)
- 下载次数: 20
发表评论
-
最强大脑第六期饶舜涵和倪梓强 他们的大脑是天生的么?
2014-02-15 01:39 2981刚看了 最强大脑第6期, 里面有两个人我比较关注 饶舜 ... -
宏碁 Acer AS4738ZG-P622G32Mncc 驱动
2011-06-13 22:37 1604主板 Intel 主板驱动 9.1.1.102 ... -
git 中文文件名 乱码 mac
2011-06-10 18:32 3645git 默认中文文件名是 xx% 是因为 对0x80以上的字 ... -
必看电影
2010-09-03 11:50 1662moxue32 提名的电影是《 ... -
jQuery.validate使用必备
2010-09-01 19:34 1291jQuery.validate使用必备 ... -
centos 雅黑
2010-04-07 15:39 1668#所有操作均在root权限下进行 1、到xp或者vi ... -
【转】西厢计划原理
2010-03-19 10:28 20982转 http://blog.youxu.info/2010 ... -
CENTOS install mysql
2010-01-21 14:53 2194当前的数据库种类比较多,有MS-SQL,Oracle,MYSQ ... -
不需要让青少年有判断力和批判力
2010-01-21 13:14 1524“不需要让青少年有判断力和批判力。只要给他们汽车、摩托车、美丽 ... -
putty中文乱码问题解决
2010-01-20 21:16 1436用putty从windows xp连接ubuntu serve ... -
vi backspace
2010-01-16 14:07 1063vi ~/.vimrc set backspace=i ... -
如何做SVN迁移
2009-07-31 10:43 1537如何做SVN 迁移 ... -
pdf 免费 转换网站
2009-04-26 13:46 12024在dig网站上看到一个在线转换pdf的网站,现在收集整理如下: ... -
ruby 遍历文件夹 所有文件
2009-04-03 17:00 7463def traverse_dir(file_path) i ... -
ruby watir 整理
2009-03-18 23:54 58555. 异常对象识别(Watir应用解决方案) Watir基于处 ... -
大姐~~~假钞不是这么做的
2009-01-06 22:20 1162大姐~~~假钞不是这么做的 楼主发帖 一妇女拿假钞去买早 ... -
JPEG 原理详细实例分析及其在嵌入式 Linux 中的应用 developerWorks
2008-11-17 01:44 1738JPEG 原理详细实例分析及其在嵌入式 Linux 中 ... -
Bmp 标准
2008-11-13 16:44 2246工具软件:工具软件:H ... -
JPEG格式 标准 规范 二进制
2008-10-27 23:14 7382JPEG格式 微处理机中的存放顺序有正序(big end ...
相关推荐
JPEG文件格式简单分析.PDF JPEG文件格式简单分析.PDF JPEG文件格式简单分析.PDF
JPEG (Joint Photographic Experts Group) 文件格式是一种广泛使用的有损图像压缩标准,特别适合于照片和其他色彩丰富的图像。...理解和解析JPEG文件的内部结构对于图像处理、压缩优化或开发相关软件具有重要意义。
本文将深入解析JPEG文件格式,帮助你理解其内部结构以及压缩原理。 首先,JPEG文件以一个特殊的文件头开始,这个头包含了文件类型标识(通常为“FF D8”)、JPEG版本信息和其他元数据。接下来是SOI(Start of Image...
通过阅读`JPEG文件16进制分析.doc`和`解码过程.doc`,可以深入了解每个步骤的细节,而`JPEG简易文档.pdf`则提供了全面的参考资料,涵盖了JPEG格式的基础知识和高级特性。 总之,理解和解析JPEG文件涉及对文件结构的...
JFIF提供了JPEG文件的兼容性和显示规范。JFIF文件标识符由`4A 46 49 46 00`(ASCII码为"JFIF\0")表示,后面跟着文件版本号,通常为`01 01`或`01 02`。 接下来的标记中,`FF C0`是基础框架(SOF0,Start of Frame)...
1. **读取JPEG文件**:使用CFile类或者CArchive类读取JPEG文件的内容,通常需要处理二进制数据流,因为JPEG文件是以二进制格式存储的。 2. **解析JPEG数据**:使用MFC中的CImage类或其他第三方库,如FreeImage,来...
尽管由于其较大的文件大小,在网络传输和移动应用领域不如JPEG、PNG等格式流行,但在图像处理和分析方面,BMP文件格式依然占有重要的地位。 #### 二、BMP文件格式的特点 1. **无损压缩**:BMP文件格式通常不使用...
6. 写入JPEG文件:构建JPEG文件的头部信息和数据块,然后将编码后的数据写入文件。 在提供的文件列表中,`main.c`很可能是实现这个转换功能的主程序,它调用了其他如`jpg.h`中定义的函数。`try1.bmp`是测试用的输入...
在IT领域,JPEG(Joint Photographic Experts Group)是一种广泛使用...掌握这些技能对于开发任何涉及到图像处理的项目都是至关重要的,无论你是想创建一个简单的图片查看器,还是在更复杂的图像分析或编辑应用中工作。
1. **文件读取**:使用PaintX库读取JPEG文件的二进制数据,这些数据包含JPEG的头部信息和压缩的图像数据。 2. **解码过程**:根据JPEG标准,解码器解析头部信息,找到每个8x8像素块的DCT系数,并应用反量化和反离散...
JFIF是一个简单且普遍接受的JPEG文件格式,它包含了一个JPEG流以及一些元数据,如图像分辨率、颜色空间信息等。JFIF文件通常以`.jpg`或`.jpeg`为扩展名。文件头包含了指示JPEG编码和解码所需的信息,使得任何支持...
- **JPEG (Joint Photographic Experts Group)**:JPEG是一种有损压缩的格式,适合存储照片类图像,通过压缩可以大幅度减小文件大小,但会损失部分图像质量。 - **BMP (Bitmap)**:BMP是Windows操作系统中常用的...
### BMP文件格式分析 BMP(Bitmap)是一种标准的位图图像格式,广泛应用于Windows操作系统中,用于存储静态图像。由于其结构简单、无压缩、兼容性好等特点,BMP格式成为了初学者学习图像处理算法的理想选择。下面,...
解码库的Demo程序可能包含了读取JPEG文件、解析其JFIF头信息、解码图像数据以及生成BITMAP对象的步骤。通过运行Demo,开发者可以直观地了解这些过程,从而更好地理解和掌握JPEG解码的原理。 在学习和使用这个库时,...
常见的方法是查找文件头的特定字节序列,如JPEG文件通常以“FF D8 FF E0”开头。 2. 数据结构和模式匹配:为了识别不同文件格式,可能使用了预定义的数据结构(如哈希表或数组)存储各种文件类型的特征,然后将这些...
Python-fleep是一个用于识别文件类型的Python库,它通过分析文件的“签名”或“魔数”来确定文件的格式。这个库特别适用于处理未知类型的二进制文件,可以帮助开发者更准确地识别和处理各种文件。在本文中,我们将...