Jpeg计算最大尺寸

Mag*_*ero 10 java applet jpeg

我不得不说我对文件格式的工作方式知之甚少.我的问题是我有一个200像素×200像素的jpeg文件,如何计算文件可能以兆字节/字节为单位的最大大小?

我认为导致这个问题的推理会帮助一些人回答我.我有一个Java Applet上传人们用它绘制到我服务器的图像.我需要知道这个文件可以达到的最大大小.它总是200x200.

这听起来很愚蠢,但有没有采取更多的字节大小的色彩,其他人如果有什么是最昂贵的一个?

mat*_*tja 24

有很多方法可以制作非常大的"病态"JPEG/JFIF文件.

在频谱的最末端,对大小没有限制,因为标准不限制某些类型的标记出现不止一次 - 例如,一个JFIF文件充满了许多GB的DRI(定义重启间隔)标记,然后是最后的8x8像素MCU在技术上是有效的.

如果我们将自己限制为"正常"标记使用,那么我们发现上限如下:

一些背景 -

  1. JPEG将像素编码为8×8像素块(DCT块)的MCU(组),每个组件(Y,Cb,Cr)的一个DCT块.

  2. 为了获得最佳压缩(和最小尺寸),使用4:2:0色度子采样方案,其中省略了75%的色度信息.为了获得最佳质量(和最大尺寸),文件是2/3的色度,1/3亮度信息.

  3. 霍夫曼比特流符号用于编码DCT分量,其中每DCT块高达65个(64 AC + 1 DC).

  4. 霍夫曼符号的范围可以是1到16位,并且编码器选择尽可能小; 但是,可以指定符号长度的选择.

  5. 必须完成霍夫曼比特流的最终编码,以便可以唯一地识别标记.即,输出中出现的0xff字节必须由两个字节替换 - 0xff,0x00.

使用所有这些信息,我们可以构建一个病态但有效的JPEG文件,libjpeg(最常见的JPEG解码器实现)很乐意解码.

首先,我们需要尽可能长的霍夫曼符号.首先想到的是,定义所有1的最大长度霍夫曼符号(16位)将使用大多数空间,但是libjpeg拒绝处理全部为1的霍夫曼符号,这似乎不被标准排除 - 如它仍然是一个独特的符号,因为与其他可变长度符号不同,已知大小为16位,实际上一些解码器可以处理它(JPEGSnoop).

所以我们定义一个霍夫曼表,它设置最后两个符号如下:

11111111_1111110  -> (0,0) (EOB - end of block value)
11111111_11111110 -> (0,15)
Run Code Online (Sandbox Code Playgroud)

这样的霍夫曼表将出现在JPEG文件中:

0xFF, 0xC4 ; DHT - define huffman table
0x00, 35 ; length
0x00 ; DC 0
1,1,1,1,1,1,1,1,1,1, 1, 1, 1, 1, 1, 1 ; histogram
1,2,3,4,5,6,7,8,9,10,11,12,13,14,0,15 ; symbols
Run Code Online (Sandbox Code Playgroud)

现在编码一个最大长度的DCT块:

1 x DC of 31 bits  ( 11111111 11111110 11111111 1111111 )
64 x AC of 31 bits ( 11111111 11111110 11111111 1111111 )
= 2015 bits
Run Code Online (Sandbox Code Playgroud)

由于MCU将是3个DCT模块(每个组件一个),因此MCU大小为6045位.

这些字节中的大多数将是0xff,根据标准,输出流中的0xff替换为0x00,以便区分比特流和有效标记.

执行此映射,完整的DCT由以下字节模式的8个重复表示:

0xff,0x00,0xfe,0xff,0x00,0xff,0x00
0xff,0x00,0xfd,0xff,0x00,0xff,0x00
0xff,0x00,0xfb,0xff,0x00,0xff,0x00
0xff,0x00,0xf7,0xff,0x00,0xff,0x00
0xff,0x00,0xef,0xff,0x00,0xff,0x00
0xff,0x00,0xdf,0xff,0x00,0xff,0x00
0xff,0x00,0xbf,0xff,0x00,0xff,0x00
0xff,0x00,0x7f,0xff,0x00
Run Code Online (Sandbox Code Playgroud)

总计8*54 = 432字节

添加所有这些,我们有:3个组件*(每个组件432个字节)=每8x8像素1296个字节

SOI/DHT/DQT/SOS段需要339字节的标题来设置图像属性和霍夫曼表,需要一个2字节的EOI标记来结束图像.

由于200x200图像为25x25 MCU,因此我们的最终尺寸为:

339 +(25*25*1296)+ 2 = 810341字节

每像素略高于20.25字节,比未压缩的BMP/TGA大6倍.


Amb*_*ber 11

作为一个经验法则,没有JPEG将是比同等尺寸的32位位图大.32位位图在图像中每个像素有4个字节,因此将这些维度相乘(200x200 = 40000),然后乘以4个字节(40000x4 = 160000),你将得到一个字节的上限 - 对于例如,160000字节大约是156kb.

  • 我从未说过JPEG使用32位作为像素.我说32位位图(最常见的类型)使用32位作为像素 - 并且JPEG总是小于等效位图(因为位图是效率最低的格式). (3认同)