在c++中读取PNG

问题描述 投票:0回答:1

我正在尝试制作一个脚本,该脚本采用 PNG 文件,读取它并将数据转换为十六进制,然后将其添加到新文件中。我编写了脚本,一切正常,只是读取并发送到新文件的信息部分不正确。 这是我的脚本:

#include <iostream>
#include <fstream>

int main()
{
    std::ofstream newImage("gradient-test.txt");
    std::fstream Image("rainbow-gradient-test.png");
    Image.seekg(0, std::iostream::end);
    int size = Image.tellg();

    for (int target = 0; target <= size; target += 1)
    {
        Image.seekg(target, std::iostream::beg);
        int color = Image.peek();
        newImage << std::hex << color;
        newImage << " ";
    }
    newImage.close();
    return 0;
}

这是rainbow-gradient-test.png: 彩虹梯度测试.png

这是gradient-test.txt的内容:

89 50 4e 47 a a ffffffff a 0 0 0 d 49 48 44 52 0 0 0 80 0 0 0 44 8 2 0 0 0 c6 25 aa 3e 0 0 0 c2 49 44 41 54 78 5e ed d4 81 6 c3 30 14 40 d1 b7 34 dd ff ff 6f b3 74 56 ea 89 12 6c 28 73 e2 aa 34 49 3 87 d6 fe d8 7b 89 bb 52 8d 3b 87 fe 1 0 80 0 0 10 0 0 2 0 40 0 0 8 0 0 1 0 20 0 0 4 0 80 0 0 10 0 0 2 0 40 0 0 8 0 0 1 0 20 0 0 0 d4 5e 6a 64 4b 94 f5 98 7c d1 f4 92 5c 5c 3e cf 9c 3f 73 71 58 5f af 8b 79 5b ee 96 b6 47 eb f1 ea d1 ce b6 e3 75 3b e6 b9 95 8d c7 ce 3 39 c9 af c6 33 93 7b 66 37 cf ab bf f9 c9 2f 8 80 0 0 10 0 0 2 0 40 0 0 8 0 0 1 0 20 0 0 4 0 80 0 0 10 0 0 2 0 40 0 0 8 0 0 1 0 20 0 0 8c 37 db 68 3 20 fb ed 96 65 0 0 0 0 49 45 4e 44 ae 42 60 82 ffffffff 

我不想使用任何额外的库。

我尝试过使用不同的方法来读取我能理解的PNG文件,但没有任何效果。我对 C++ 编程还比较陌生,所以请跟我讲一下。非常感谢任何帮助。谢谢!

c++ file hex png
1个回答
0
投票

我发现这个小代码有很多问题:

  1. 您可以使用

    std::filesystem::file_size()
    或等效项,而不是使用
    Image.seekg()
    +
    Image.tellg()
    。此外,您的循环存在超出文件大小范围的 off-by-1 错误。 但是,在这种情况下,您实际上根本不需要文件大小,因为您可以使用
    Image.get()
    而不是
    Image.seekg()
    +
    Image.peek()
    ;

  2. 您应该使用

    std::ifstream
    而不是
    std::fstream
    。无论哪种方式,请以
    binary
    模式打开 PNG 文件,以避免任何数据转换,例如换行符翻译。

  3. peek()
    返回带符号的
    int
    。如果一个字节的高位设置为 1,则存在“符号扩展”返回值的风险。 您必须屏蔽掉不需要的位。 此外,失败时 peek() 返回
    Traits::eof()
    ,在本例中是
    EOF
    常量,它具有您未处理的负整数值。
    
    

  4. 您不包括您正在使用的 I/O 操纵器的
  5. <iomanip>

    
    

  6. 试试这个:

#include <iostream> #include <iomanip> #include <fstream> int main() { std::ofstream newImage("gradient-test.txt"); std::ifstream Image("rainbow-gradient-test.png", std::ios::binary); char ch; std::cout << std::hex << std::setfill('0'); while (Image.get(ch)) { newImage << std::setw(2) << static_cast<unsigned>(ch) << ' '; } newImage.close(); return 0; }

	
© www.soinside.com 2019 - 2024. All rights reserved.