ffmpeg-jpeg图片格式详解

本文详细介绍了JPEG图片格式,包括其三种形式:标准JPEG、渐进式JPEG和JPEG2000。重点讲解了JPEG的压缩过程,包括颜色转换、DCT变换、量化和编码。还探讨了JPEG文件的段类型,如SOI、APP0、DQT、SOF0、DHT、SOS和EOI等,并提供了JPEG压缩编码的实例。
摘要由CSDN通过智能技术生成

jpg/jpeg是24位的图像文件格式,也是一种高效率的压缩格式

JPEG格式可以分为
1、标准JPEG:只有图片完全被加载和读取完毕之后,才能看到图片的全貌
2、渐进式JPEG:(标准的改进)首先呈现图片的大概外貌,然后再逐渐呈现具体的细节部分
3、JPEG2000三种格式:作为JPEG的升级版,JPEG2000的压缩率比标准JPEG高约30%,同时支持有损压缩和无损压缩。它还支持渐进式传输,即,先传输图片的粗略轮廓,然后,逐步传输细节数据,使得图片由模糊到清晰逐步显示。此外,JPEG2000还支持感兴趣区域,也就是说,可以指定图片上感兴趣区域的压缩质量,还可以选择指定的部分先进行解压。

JPEG格式压缩的主要是高频信息,对色彩的信息保留较好,适合应用于互联网,可减少图像的传输时间,可以支持24bit真彩色,也普遍应用于需要连续色调的图像。JPEG由于可以提供有损压缩,因此压缩比可以达到其他传统压缩算法无法比拟的程度。
  其压缩模式有以下几种:顺序式编码(SequentialEncoding),递增式编码(ProgressiveEncoding),无失真编码(LosslessEncoding)和阶梯式编码(HierarchicalEncoding)。
  
  JPEG的压缩,分为四个步骤:
  (1)颜色转换:由于JPEG只支持YUV颜色模式,而不支持RGB颜色模式,所以在将彩色图像进行压缩之前,必须先对颜色模式进据转换。转换完成之后还需要进行数据采样。一般采用的采样比例是2:1:1或4:2:2。由于在执行了此项工作之后,每两行数据只保留一行,因此,采样后图像数据量将压缩为原来的一半。
  (2)DCT变换:DCT(DiscreteConsineTransform)是将图像信号在频率域上进行变换,分离出高频和低频信息的处理过程。然后再对图像的高频部分(即图像细节)进行压缩,以达到压缩图像数据的目的。首先将图像划分为多个8*8的矩阵。然后对每一个矩阵作DCT变换(变换公式此略)。变换后得到一个频率系数矩阵,其中的频率系数都是浮点数。
  (3)量化:由于在后面编码过程中使用的码本都是整数,因此需要对变换后的频率系数进行量化,将之转换为整数。由于进行数据量化后,矩阵中的数据都是近似值,和原始图像数据之间有了差异,这一差异是造成图像压缩后失真的主要原因。
  (4)编码:编码采用两种机制:一是0值的行程长度编码;二是熵编码(EntropyCoding)。在JPEG中,采用曲徊序列,即以矩阵对角线的法线方向作“之”字排列矩阵中的元素。这样做的优点是使得靠近矩阵左上角、值比较大的元素排列在行程的前面,而行程的后面所排列的矩阵元素基本上为0值。行程长度编码是非常简单和常用的编码方式,在此不再赘述。编码实际上是一种基于统计特性的编码方法。在JPEG中允许采用HUFFMAN编码或者算术编码。

2.识别:前面3个字节:FF D8 FF

//SkImageDecoder_libjpeg.cpp (external\skia\src\images)
static bool is_jpeg(SkStream* stream) {
   
    //需要匹配的字节
    static const unsigned char gHeader[] = {
    0xFF, 0xD8, 0xFF };
    static const size_t HEADER_SIZE = sizeof(gHeader);

    char buffer[HEADER_SIZE];
    //从数据源中读取3个字节
    size_t len = stream->read(buffer, HEADER_SIZE);

    if (len != HEADER_SIZE) {
   
        return false;   // can't read enough
    }
    //只有完全匹配才会认为是jpeg图片
    if (memcmp(buffer, gHeader, HEADER_SIZE)) {
   
        return false;
    }
    return true;
}

3.JPEG图片格式详解

在这里插入图片描述

1.        SOI  0xD8          	图像开始 
2.        APP0 0xE0 (图像识别信息)   JFIF应用资料块 
3.        APPn 0xE1 - 0xEF           	其他的应用资料块(n, 115) 
4.        DQT  0xDB           量化表 
5.        SOF0 0xC0           	帧开始 
6.        DHT  0xC4           霍夫曼(Huffman)//DRI(定义重新开始间隔 非必须)
7.        SOS  0xDA           扫描线开始 
8.        EOI  0xD9           图像结束

JPEG 文件的格式是分为一个一个的段来存储的,段的多少和长度并不是一定的
注意:这个长度的表示方法是按照高位在前,低位在后的,与 Intel 的表示方法不同。比方说一个段的长度是0x12AB,那么它会按照0x12,0xAB的顺序存储。但是如果按照Intel的方式:高位在后,低位在前的方式会存储成0xAB,0x12,而这样的存储方法对于JPEG是不对的。这样的话如果一个程序不认识JPEG文件某个段,它就可以读取后两个字节,得到这个段的长度,并跳过忽略它。

微处理机中的存放顺序有正序(big endian)和逆序(little endian)之分。正序存放就是高位元组存放在前低位元组在後,而逆序存放就是低位元组在前高位元组在後。例如,十六进位数爲A02B,正序存放就是A02B,逆序存放就是2BA0。摩托罗拉(Motorola)公司的微处理器使用正序存放,而英代尔(Intel)公司的微处理器使用逆序。JPEG文件中的位元组是按照正序排列的。

-----------------------------------------------------------------
名称  字节数     数据  说明
-----------------------------------------------------------------
段标识   1         FF      每个新段的开始标识
段类型   1                 类型编码(称作“标记码”)
段长度   2                 包括段内容和段长度本身,不包括段标识和段类型
段内容                     ≤65533字节

①JPG 文件中所有关于宽度高度长度间隔这一类数据,凡是>1字节的,均采用Motorola格式,即:高位在前,低位在后。
②有些段没有长度描述也没有内容,只有段标识和段类型。文件头和文件尾均属于这种段。
③段与段之间无论有多少FF都是合法的,这些FF称为“填充字节”,必须被忽略掉。

3.0段类型

---------------------------------------
名称  标记码     说明
---------------------------------------
SOI     D8          文件头
EOI     D9          文件尾
SOF0    C0          帧开始(标准 JPEG)
SOF1    C1          同上
DHT     C4          定义 Huffman 表(霍夫曼表)
SOS 	DA          扫描行开始
DQT 	DB          定义量化表
DRI     DD          定义重新开始间隔
APP0    E0          定义交换格式和图像识别信息
COM   	FE          注释
-----------------------------------------------------------
说明:有的文章也将DNL段(标记码=DC,定义扫描行数)列为必须段。
ps:段类型有
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值