Jpeg计算最大尺寸

时间:2010-04-29 03:56:04

标签: java applet jpeg

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

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

这听起来很愚蠢,但有些颜色比其他颜色更多,如果是这样,最昂贵的是什么?

5 个答案:

答案 0 :(得分:24)

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

在光谱的最末端,尺寸没有限制,因为标准不限制某些类型的标记出现不止一次 - 例如一个JFIF文件,其中包含许多GB的DRI(定义重启间隔)标记,最后一个8x8像素的MCU在技术上是有效的。

如果我们将自己限制在“正常”标记使用情况,那么我们会发现上限如下:

一些背景 -

  1. JPEG将像素编码为8x8像素块(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。

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

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

    因此我们定义了一个霍夫曼表,它将最后两个符号设置如下:

    11111111_1111110  -> (0,0) (EOB - end of block value)
    11111111_11111110 -> (0,15)
    

    这样的霍夫曼表将在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
    

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

    1 x DC of 31 bits  ( 11111111 11111110 11111111 1111111 )
    64 x AC of 31 bits ( 11111111 11111110 11111111 1111111 )
    = 2015 bits
    

    由于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
    

    总计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倍。

答案 1 :(得分:11)

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

答案 2 :(得分:3)

JPEG的最大可能大小应该在width * height * 12 bits左右。

JPEG将图像转换为不同的颜色空间(YCbCr),使用较少的位(确切地说是12个)来表示单个颜色。但实际上,图像会比上面的公式所暗示的要小得多。

如果我们仅使用无损压缩,则文件大小会稍微小一些。即使这样,也没有人这样做,所以你的图像应该远远低于该公式设定的极限。

简而言之:60 kb的上衣,但很可能更少。

答案 3 :(得分:0)

我不确定这会有所帮助,但我相信它可以是绝对最大值:

width * height * 4 (size of int)您可能还应该为元数据添加一个千字节...但我怀疑图像会达到那个(因为这是JPEG压缩的全部要点)

答案 4 :(得分:0)

最终大小(以字节为单位)取决于使用的编码质量设置和像素数。在您的情况下,所有图像应该是相同的大小,因为您正在进行编码,并且您的用户似乎被迫在200x200区域上绘制。

根据维基百科的说法,最大值是每像素大约9位。

所以200 * 200 * 9 = 360000位= 45 kB

http://en.wikipedia.org/wiki/JPEG#Effects_of_JPEG_compression