Jpeg 计算最大尺寸

发布于 2024-08-31 04:46:07 字数 245 浏览 2 评论 0原文

我不得不说我不太了解文件格式的工作原理。 我的问题是,我有一个 200 像素 x 200 像素的 jpeg 文件,如何计算该文件的最大大小(以兆字节/字节为单位)?

我认为引发这个问题的推理将有助于有人回答我。我有一个 Java Applet,可以将人们用它绘制的图像上传到我的服务器。我需要知道该文件可以达到的最大大小。它始终是 200x200。

这听起来很愚蠢,但是是否有比其他颜色占用更多字节大小的颜色,如果是的话,最昂贵的颜色是什么?

I have to say the I don't know much about how file formats work.
My question is say I have a jpeg file that is 200 px by 200 px, how can one calculate what the maximum size that file could be in terms of megabytes/bytes?

I think that the reasoning that led to the question will help some one answer me. I have a Java Applet the uploads Images that people draw with it to my server. I need to know what the max size that this file can conceivably reach. It is always going to be 200x200.

It sounds dumb but are there colors that take more byte size then others and if so what is the most expensive one?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

沙与沫 2024-09-07 04:46:07

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

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

如果我们将自己限制为“正常”标记使用,那么我们会找到如下上限:

一些背景 -

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

  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)

这样的霍夫曼表将出现在 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 倍多。

There are many ways to make a 'pathological' JPEG/JFIF file that is unusually large.

At the extreme end of the spectrum there is no limit to the size, since the standard doesn't limit some types of marker appearing more than once - e.g. a JFIF file full of many GB of DRI (define restart interval) markers and then an 8x8 pixel MCU at the end is technically valid.

If we restrict ourselves to 'normal' marker usage then we find an upper limit as follows :

Some background -

  1. JPEG encodes pixels as a MCU (group) of 8x8 pixel blocks (DCT blocks), one DCT block for each component (Y, Cb, Cr).

  2. To get best compression (and smallest size), a 4:2:0 chroma subsampling scheme is used where 75% of the chroma information is omitted. To get best quality (and largest size), the file is 2/3rd's chroma, 1/3rd luminance info.

  3. Huffman bitstream symbols are used to encode DCT components, of which there are up to 65 per DCT block (64 AC + 1 DC).

  4. Huffman symbols can range from 1 to 16 bits and are chosen by the encoder to be as small as possible; However, the choice of symbol length can be specified.

  5. Final encoding of the huffman bitstream must be done so that markers can be uniquely identified. I.e, any occurance of a 0xff byte in the output must be replaced by two bytes - 0xff,0x00.

Using all this information we can construct a pathological, but valid, JPEG file which libjpeg (the most common JPEG decoder implementation) is happy to decode.

First, we need the longest possible huffman symbols. At first thought, defining a maximal-length huffman symbol (16 bits) of all 1's, would use most space, however libjpeg refuses to handle a Huffman symbol which is all 1's, this doesn't seem to be excluded by the standard - as it still a unique symbol as the size is already known to be 16 bits unlike other variable-length symbols, and indeed some decoders can handle it (JPEGSnoop).

So we define a huffman table which sets the last two symbols as follows :

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

Such a huffman table would appear in a JPEG file as :

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

Now to encode a maximal-length DCT block :

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

Since an MCU will be 3 DCT blocks (one for each component), the MCU size will be
6045 bits.

Most of these bytes will be 0xff, which are replaced by 0xff,0x00 in the output stream, as per the standard, in order to differentiate the bitstream from valid markers.

Perform this mapping and a complete DCT is represented by 8 repeats of the following byte pattern :

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

which totals 8*54 = 432 bytes

Adding all this up, we have :
3 components * (432 bytes per component)
= 1296 bytes per 8x8 pixels

a header of 339 bytes is required for the SOI/DHT/DQT/SOS segments to setup the image properties and huffman tables, a 2 byte EOI marker is required to end the image.

Since a 200x200 image would be 25x25 MCU's, we have a final size of :

339 + (25 * 25 * 1296) + 2
= 810341 bytes

which works out as a little over 20.25 bytes per pixel, over 6 times larger than an uncompressed BMP/TGA.

一杆小烟枪 2024-09-07 04:46:07

根据经验,任何 JPEG 都不会大于同等大小的 32 位位图。 32 位位图图像中每个像素有 4 个字节,因此将尺寸相乘 (200x200 = 40000),然后乘以 4 个字节 (40000x4 = 160000),您将得到一个以字节为单位的上限 - 对于你的例子,160000字节大约是156kb。

As a rule of thumb, no JPEG is going to be larger than an equivalent size 32-bit bitmap. A 32-bit bitmap will have 4 bytes per pixel in the image, so multiply the dimensions together (200x200 = 40000), then multiply that by 4 bytes (40000x4 = 160000), and you'll have an upper bound in bytes - for your example, 160000 bytes is approximately 156kb.

孤独患者 2024-09-07 04:46:07

JPEG 的最大可能大小应约为宽度 * 高度 * 12 位

JPEG 将图像转换为不同的颜色空间 (YCbCr),该空间使用更少的位(确切地说是 12 位)来表示单一颜色。但实际上,图像将比上述公式建议的小得多。

如果我们仅使用无损压缩,文件大小会小一些。即使如此,也没有人这样做,因此您的图像应该远低于该公式设置的限制。

简而言之:最多 60 kb,但很可能要少得多。

The maximum possible size a JPEG can be should be somewhere around width * height * 12 bits.

JPEG converts images to a different color space (YCbCr) which uses fewer bits (12 to be exact) to represent a single color. Realistically speaking though, the image will be much smaller than the above formula would suggest.

If we use lossless compression only, the file size would be a bit smaller. Even then, no one does that so your image should be far below the limit set by that formula.

In short: 60 kb tops, but most likely way less.

街角卖回忆 2024-09-07 04:46:07

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

但根据 wikipedia,最大值大约为每像素 9 位。

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

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

The final size in bytes is based on the encoding quality settings used and the number of pixels. In your case, all images should be the same size since you are doing the encoding and your user seems forced to draw on a 200x200 area.

According to wikipedia though, the maximum is roughly 9 bits per a pixel.

So 200*200*9 = 360000 bits = 45 kB

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

甜`诱少女 2024-09-07 04:46:07

我不确定这是否有帮助,但我相信它的绝对最大值可能是:

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

I'm not sure this would be that helpful, but I believe that the absolute maximum it could be would be:

width * height * 4 (size of int) You should probably also add in a maybe a kilobyte for metadata... but I doubt the image would EVER reach that (as that is the whole point of JPEG compression)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文