如何从寻找目标C头提取PNG的宽度和高度? [英] How do I extract the width and height of a PNG from looking at the header in objective c?

查看:236
本文介绍了如何从寻找目标C头提取PNG的宽度和高度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要在网上找到的图像的尺寸,而无需下载它们。要做到这一点我做到这一点:

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

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

   // Send a synchronous request
    NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString: url]];
    NSString *rangeString = [url hasSuffix: @"png"] ? @"bytes=0-100" : @"bytes=0-1300";
    [urlRequest setValue:rangeString forHTTPHeaderField:@"Range"];
    NSURLResponse * response = nil;
    NSError * error = nil;
    NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest
                                          returningResponse:&response
                                                      error:&error];
    if (error == nil)
        return [UIImage imageWithData: data].size;
    else
        return CGSizeMake(0, 0);

}

这(下载前100个字节),令人惊讶的作品,我也得到了正确的尺寸PNG格式这种方式。

This (downloading the first 100 bytes) surprisingly works and I get the correct dimensions for PNGs this way.

不过,我不认为这是一个非常优雅的方式。首先,我选择了通过只是猜测和检查下载前100个字节,使它尽可能小,同时仍然有它的工作好了。

However I do not think this is a very elegant approach. First, I chose to download the first 100 bytes by just guess and checking, making it as small as possible whilst still having it work okay.

显然,在一个PNG文件有这个东西叫做IHDR在头,我必须找到它,并直接后是宽度和高度。这使我在IM pression,我应该遍历所有的数据,并发现这IHDR并获得尺寸。问题是,当我的NSLog数据我得到的是这样的:

Apparently in a PNG file there's this thing called a IHDR in the header and I have to find it and directly after it are the width and height. This gives me the impression that I should loop over the data and find this IHDR and get the dimensions. The problem is, when I NSLog the data I get something like this:

... 49484452 000003b7 000001a7 08060000 006c2da0 b100000a 41694343 50494343 2050726f 66696c65 ...

我不知道如何处理循环在我的NSData对象和检测IHDR令牌,然后转换后,浮现在数字的事。我不知道,如果请求一个PNG只有100字节请求太多刚拿到的尺寸,或者如果它要求不够

I have no idea how to handle looping over my NSData object and detecting the IHDR token and then converting the things that come after it to numbers. I also have no idea if requesting just 100 bytes for a PNG is requesting too much just to get the dimensions, or if it's requesting not enough

推荐答案

按照 PNG规范

在第一个的PNG文件科幻总是包含以下八个字节
  (十进制)值:137 80 78 71 13 10 26 10

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

所以,你必须读那些以确保你真的有一个PNG文件。

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

然后,

该IHDR块必须出现。它包含:

The IHDR chunk must appear FIRST. It contains:

宽度:4个字节

身高:4个字节

等等......

所以,根据大块的结构,你首先要阅读的字节重新presenting块的数据字段的长度,然后在字节再presenting块的名字,那么这两个32位整数重新presenting的宽度和高度, 8 的总字节数。

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.

所以,字节的确切数量最少必须为了读取以确定宽度和高度为8 + 4 + 4 + 8 = 24字节

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

一旦你的NSData对象,你只需要访问字节,它包含:

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];

可选的,但我推荐它强烈,请检查您确实有一个PNG文件:

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 !
}

请确保你有一个IHDR:

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
}

宽度和高度可以为大端 EN codeD无符号整数访问偏移24负8和零下4个字节分别为:

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);

修改:固定缓冲存储器读取code:PNG实际存储在大端整数

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

这篇关于如何从寻找目标C头提取PNG的宽度和高度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆