5

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

たとえばWikipediaのこの画像から読み取ろうとすると、これらの間違った値が得られます。

252097920 (800 のはずです)
139985408 (600 のはずです)

この関数はfalse を返さないことに注意してください。そのため、幅変数と高さ変数の内容はファイルから取得する必要があります。

4

2 に答える 2

8

1バイトずれているようです:

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

PNG 仕様では、ヘッダーの長さは 8 バイトであるため、代わりに「9」を「8」にする必要があります。位置は 0 から始まります。

また、仕様では、整数はネットワーク (ビッグ エンディアン) オーダーであると記載されているため、リトルエンディアン システムを使用している場合は、 ntohl()を使用するか、バイト オーダーを変換する必要がある場合があります。

ただし、学習のためにこれを行っている場合を除き、png を自分で解析しようとするのではなく、libpngstb_imageなどを使用する価値があるでしょう。

于 2012-12-29T16:51:13.360 に答える
3

Portable Network Graphics Technical detailsを見ると、署名は 9 ではなく 8 バイトであると書かれています。

さらに、システムのバイト順が PNG 標準と同じであると確信していますか? ntohl(3)は正しいバイト順を保証します。Windowsでも利用できます。

于 2012-12-29T16:51:52.097 に答える