Jpeg calculating max size

后端 未结 5 2050
灰色年华
灰色年华 2021-02-08 00:19

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 th

相关标签:
5条回答
  • 2021-02-08 00:40

    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.

    0 讨论(0)
  • 2021-02-08 00:51

    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.

    0 讨论(0)
  • 2021-02-08 00:52

    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)

    0 讨论(0)
  • 2021-02-08 00:56

    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.

    0 讨论(0)
  • 2021-02-08 00:57

    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

    0 讨论(0)
提交回复
热议问题