我正在尝试读取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; }如果我尝试从维基百科的这幅图像读取例子,我得到这些错误的值:
252097920(应该是800) 139985408(应该是600)
请注意,函数不返回false,因此宽度和高度变量的内容必须来自文件。
I am experimenting with reading the width and height of a PNG file. This is my code:
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; }If I try to read for example from this image from Wikipedia, I'm getting these wrong values:
252097920 (should be 800) 139985408 (should be 600)
Note that the function is not returning false so the contents of the width and height variables must come from the file.
最满意答案
它看起来像你关了一个字节:
// Skip PNG file signature file.seekg(9, std::ios_base::cur);PNG规范说头标长度为8个字节,所以你希望“9”代替“8”。 职位从0开始。
还要注意规范说明整数是网络(big-endian)顺序 ,所以如果你使用的是小端系统,你可能需要或需要使用ntohl()或者转换字节顺序。
可能值得使用libpng或stb_image或类似的东西,而不是尝试自己解析png,除非你这样做是为了学习。
It looks like you're off by a byte:
// Skip PNG file signature file.seekg(9, std::ios_base::cur);The PNG Specification says the header is 8 bytes long, so you want that "9" to be an "8" instead. Positions start at 0.
Also note that the spec says that integers are in network (big-endian) order, so you may want or need to use ntohl() or otherwise convert byte order if you're on a little-endian system.
It's probably worth using libpng or stb_image or something similar rather than attempting to parse the png yourself, though -- unless you're doing this to learn.
更多推荐
发布评论