【问题标题】:Copying picture (.tga) from text content从文本内容复制图片 (.tga)
【发布时间】:2019-01-27 18:13:53
【问题描述】:

我致力于创建游戏。我想隐藏我所有的 .tga 文件。 我将我所有文件的字符串内容连接到一个文件中,以使其对玩家不可见。 我希望我的程序通过创建一个临时的 .tga 文件来加载图片 保存的内容。

因此,我正在尝试从原始文件的内容中复制一个 .tga 文件。 更准确地说,我将 .tga 文件作为文本读取并写入。 尽管 Notepad++ 发现原始文件和新文件相同,但新文件不能作为 .tga 文件打开。 Windows 检测偏移量为 1 字节的文件的大小。

你能解释一下我做错了什么吗? 或者可能会建议我一个更好的方法来隐藏我的文件。

问候

【问题讨论】:

  • 那个问题和c++有什么关系,你的问题没有涉及c++代码。
  • tga 不是基于文本的文件格式,而是二进制格式。使用旨在使用文本复制二进制数据的编辑器肯定会导致数据损坏。所以使用适当的工具来连接多个二进制文件。
  • 很难就我们看不到的程序中的错误提出建议...如果您希望在文本中显示二进制图像文件(例如tga) b> 编辑器,考虑 base64 编码。
  • 首先,@t.niese 所说的。使用二进制数据作为字符串是一个很大的禁忌。其次,即使您连接二进制数据,任何有权访问它并了解 TGA 格式规范的人都可以轻松地恢复数据。(例如 paulbourke.net/dataformats/tga )。我建议您研究现有的许多可用开源引擎使用的打包游戏数据的方法。

标签: c++ tga


【解决方案1】:

更准确地说,我将 .tga 文件作为 文本 读取并写入

这可能是您的问题所在:您必须将 .tga 文件作为二进制文件进行读写。否则,字节序列 0x0D 0x0A(CR LF,Windows 行结束)的任何出现都可能被单个 0x0A(LF,Unix 行结束)替换,反之亦然,或者 0x1A(文件的 DOS 结束)可能被剥离或附加。根据您使用的代码,您最终可能还会剥离任何 0x00 (NUL) 字节。

【讨论】:

  • 感谢您的提示。我会尝试在我的代码中以二进制内容的形式读写,然后我会回来。
【解决方案2】:

我尝试使用我的程序 (c++) 将 .tga 文件作为二进制文件读取/写入,但生成的文件仍然损坏。代码如下。

std::string name = "my_picture.tga";
std::ifstream FileIn(name, std::ios_base::binary);
std::vector<char> listChar;
bool stopp = false;
if (FileIn) {
    while (!(stopp))
    {
        char xin;
        FileIn.read(reinterpret_cast<char*>(&xin), sizeof(char));
        listChar.push_back(xin);
        if (FileIn.eof()) stopp = true;
    }
    FileIn.close();
}

std::ofstream FileOut(".\\test.tga", std::ios_base::binary);
bool isCarierReturn = false;
for (char xout : listChar) {
    isCarierReturn = xout == '\r';
    if (!isCarierReturn) FileOut.write(reinterpret_cast<const char*>(&xout), sizeof(char));
}
FileOut.close();

我在十六进制阅读器上比较了原始文件和新文件,文件实际上是不同的。

原始文件和新文件之间的区别在于行尾不匹配,而不是原始文件上只有 0x0A ('\n'),新文件具有字节序列 0x0D 0x0A ('\r' 和 ' \n')。在其他一些图片上,生成的文件不完整,中断总是在 0x1A 值之前(如@Christoph Lipka 所说)。

我设法通过测试 char 是否是载波返回来编写正确的序列,在这种情况下没有写入 char,只跳过了字节 0x0D,见下文:

std::ofstream FileOut(".\\test.tga", std::ios_base::binary);
bool isCarrierReturn = false;
char xout_p1 = '\0';
if (listChar.size() >= 1) xout_p1 = listChar.at(0);
for (unsigned i(0); i < listChar.size(); i++) {
    char xout = xout_p1;
    if (i < listChar.size() - 1) xout_p1 = listChar.at(i + 1);
    else xout_p1 = '\0';
    isCarrierReturn = xout == '\r' && xout_p1 == '\n';
    if (!isCarrierReturn) FileOut.write(reinterpret_cast<const char*>(&xout), sizeof(char));
}
FileOut.close();

文件读取不完整通过将文件读取为二进制文件来解决。

有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多