【问题标题】:Reading width and height of PNG header读取PNG标头的宽度和高度
【发布时间】:2012-12-14 13:18:35
【问题描述】:

我正在尝试读取 PNG 文件的宽度和高度。 这是我的代码:

struct TImageSize {
    int width;
    int height;
};

bool getPngSize(const char *fileName, TImageSize &is) {
    std::ifstream file(fileName, std::ios_base::binary | std::ios_base::in);

    if (!file.is_open() || !file) {
        file.close();
        return false;
    }

    // Skip PNG file signature
    file.seekg(9, std::ios_base::cur);

    // First chunk: IHDR image header
    // Skip Chunk Length
    file.seekg(4, std::ios_base::cur);
    // Skip Chunk Type
    file.seekg(4, std::ios_base::cur);

    __int32 width, height;

    file.read((char*)&width, 4);
    file.read((char*)&height, 4);

    std::cout << file.tellg();

    is.width = width;
    is.height = height;

    file.close();

    return true;
}

如果我尝试从 this image from Wikipedia 读取示例,我会得到以下错误值:

252097920(应该是800)
139985408(应该是600)

请注意,该函数返回 false,因此宽度和高度变量的内容必须来自文件。

【问题讨论】:

    标签: c++ image file file-io png


    【解决方案1】:

    看起来你差了一个字节:

    // Skip PNG file signature
    file.seekg(9, std::ios_base::cur);
    

    PNG Specification 表示标头长度为 8 个字节,因此您希望将“9”改为“8”。位置从 0 开始。

    另请注意,规范说 integers are in network (big-endian) order,因此如果您使用的是 little-endian 系统,您可能想要或需要使用 ntohl() 或以其他方式转换字节顺序。

    可能值得使用 libpngstb_image 或类似的东西,而不是尝试自己解析 png——除非你这样做是为了学习。

    【讨论】:

    • 为你们俩+1,现在可以使用了!这只是为了边做边学;)
    【解决方案2】:

    当您查看 Portable Network Graphics Technical details 时,它说签名是 8 个字节而不是 9 个。

    另外,您确定您的系统具有与 PNG 标准相同的字节顺序吗? ntohl(3) 将确保正确的字节顺序。 It's 也适用于 Windows。

    【讨论】:

    • 谢谢!我接受了他的回答,因为你比他晚了 39 秒。
    猜你喜欢
    • 2014-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    相关资源
    最近更新 更多