我正在尝试制作一个脚本,该脚本采用 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++ 编程还比较陌生,所以请跟我讲一下。非常感谢任何帮助。谢谢!
我发现这个小代码有很多问题:
您可以使用
std::filesystem::file_size()
或等效项,而不是使用 Image.seekg()
+Image.tellg()
。此外,您的循环存在超出文件大小范围的 off-by-1 错误。 但是,在这种情况下,您实际上根本不需要文件大小,因为您可以使用 Image.get()
而不是 Image.seekg()
+Image.peek()
;
您应该使用
std::ifstream
而不是 std::fstream
。无论哪种方式,请以 binary
模式打开 PNG 文件,以避免任何数据转换,例如换行符翻译。
peek()
返回带符号的 int
。如果一个字节的高位设置为 1,则存在“符号扩展”返回值的风险。 您必须屏蔽掉不需要的位。 此外,失败时 peek()
返回 Traits::eof()
,在本例中是 EOF
常量,它具有您未处理的负整数值。
<iomanip>
。
#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;
}