How do I extract the width and height of a PNG from looking at the header in objective c?

前端 未结 1 1747
陌清茗
陌清茗 2021-02-14 08:20

I have a need to find the dimensions of images online without downloading them. To accomplish this I do this:

+ (CGSize) getImageDimensions:(NSString *)url {

           


        
1条回答
  •  礼貌的吻别
    2021-02-14 08:54

    Rationale

    According to the PNG specification:

    The first eight bytes of a PNG file always contain the following (decimal) values: 137 80 78 71 13 10 26 10

    So you have to read those to make sure you really have a PNG file.

    Then,

    The IHDR chunk must appear FIRST. It contains:

    Width: 4 bytes

    Height: 4 bytes

    etc...

    So according to the structure of chunks, you first have to read the four bytes representing the length of the chunk's data field, then the four bytes representing the chunk's name, then the two 32-bit integers representing width and height, eight bytes in total.

    So, the exact minimal number of bytes you must read in order to determine width and height is 8 + 4 + 4 + 8 = 24 bytes.

    Objective-C code

    Once you have your NSData object, you simply have to access the bytes that it contains:

    unsigned char buffer[24];
    [data getBytes:buffer length:24];
    

    Optionally, but I recommend it strongly, check that you indeed have a PNG file:

    unsigned char png_header[] = {137, 80, 78, 71, 13, 10, 26, 10};
    if (memcmp(buffer, png_header, 8)) {
         // this is not a PNG !
    }
    

    Make sure you have an IHDR:

    unsigned char ihdr_name[] = "IHDR";
    if (memcmp(buffer+8+4, ihdr_name, 4)) {
        // not an IHDR chunk, invalid PNG file
    }
    

    Width and height can be accessed as big-endian encoded unsigned ints at offset 24 minus 8 and minus 4 bytes respectively:

    unsigned int width = OSReadBigInt32(buffer + 24 - 8);
    unsigned int height = OSReadBigInt32(buffer + 24 - 4);
    

    Edit: Fixed buffer reading code: PNG actually stores integers in big-endian.

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