使用 QFile 使 istringstream 作为二进制输入(对于 libpng)
Using QFile made istringstream as binary input (for libpng)
我正在尝试使用 libpng 从中读取 png
Qt 资源。问题:class 正在阅读
应该不有Qt的任何依赖性。
第一步,阅读http://www.piko3d.net/tutorials/libpng-tutorial-loading-png-files-from-streams/#CustomRead我已经成功写了一个函数
read_png(istream& in)
我也成功传递了一个普通的旧 ifstream
ifstream in("abs_path_to_png/icon.png");
到read_png(..)并成功读取png。但是如何获得
来自 Qt 资源的(最好是独立于平台的)istream?表现
不是什么大问题所以我最初想出了
bool Io_Qt::get_istringstream_from_QFile(QFile& qfile, istringstream& iss)
{
// [.. Some checking for existence and the file being open ..]
QString qs(qfile.readAll());
iss.str(qs.toStdString());
// I also tried: QByteArray arr(qfile.readAll()); iss.str(arr.data());
return qfile.isOpen();
}
// Someplace else iss and qfile are created like this:
istringstream iss(std::stringstream::in | std::stringstream::binary);
QFile qfile(":/res/icon.png");
qfile.open(QIODevice::ReadOnly);
这实际上产生了一个问题,即乍一看,看起来不错,当说
cout << "'" << iss.str().c_str() << "'" << endl;
我明白了
'�PNG
'
虽然似乎存在一些空白问题。对于
ifstream in("abs_path_to_png/icon.png");
char c;
cout << "'";
for (int j=0;j<8;j++)
{
in >> c;
cout << c;
}
cout << "'" << endl;
产量
'�PNG'
虽然后者有效,但前一个变体最终导致 libpng 检查函数 png_sig_cmp(..) 拒绝我的 png 为无效。我的第一反应是 "binary"。然而:
- istringstream iss(std::stringstream::in | std::stringstream::binary);感觉不错。
- QIODevice::ReadOnly 似乎没有二进制伙伴。
你看到我错过了什么了吗?
您正在处理流,就像处理带有词法提取运算符的文本数据一样。查看 ios::binary
以及适用于二进制流的 read
和 write
方法。
我会完全放弃 operator<<
和 operator>>
以支持 read
和 write
。使用 ostream::write
写入从 QIODevice::readAll()
返回的字节数组数据以将其内容传输到您的临时字符串流,例如,并在您的测试中使用 ostream::read
来验证其内容。
确保正确传输的一个很好的测试用例是编写一个测试,从 QFile 读取内容,使用 ostream::write
将其传输到二进制输出文件流(ofstream
),然后尝试用图像软件加载它,看看是否可以。然后将您的文件流与字符串流交换,并在您工作时将其传递给 libpng
。
正如艾克所说,这似乎确实是关于两者之间的差异
以文本为中心的运算符“>>”、“<<”和类似“.str(..)”的东西
以二进制为中心的命令,如“.read”和“.write”。加上它是
关于正确初始化流。当我终于得到程序
做我想做的福音是这样的:
首先,我在 QFile 旁边使用了一个普通的字符串流:
// Explicitly setting flags should at least contain ::in and ::out
// stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary)
// However, the default constructor is perfectly fine.
stringstream ss;
QFile qfile(":/res/icon.png");
qfile.open(QIODevice::ReadOnly);
这是我传递给我的函数,现在看起来像这样:
bool Io_Qt::get_stringstream_from_QFile(QFile& qfile, stringstream& ss)
{
// [.. some sanity checks..]
QDataStream in(&qfile);
uint len = qfile.size();
char* c = (char*)malloc(len*sizeof(char));
in.readRawData(c,len);
ss.write(c,len);
free (c);
return true;
}
此流已填充,并且大小合适。特别是从
.write(..) 写入所需数量的字符,无论
数据中有多少个零。我最大的问题是
我不愿意同时拥有 std::stringstream::in 和
std::stringstream::out同时激活因为
组合对我来说似乎有些古怪。然而两者都是需要的。
但是,我发现我可以跳过std::stringstream::binary。
但是因为它似乎没有任何伤害我喜欢
保持好运。不过,请随意评论这个迷信! :-)
更干净、更少 C 风格、更多 Qt/C++ 风格的版本可以是:
QFile file(filePath);
file.open(QIODevice::ReadOnly);
QByteArray data = file.readAll();
std::istringstream iss(data.toStdString());
现在使用 iss
,在我的例子中,这是用于 libTIFF:
TIFF* tif = TIFFStreamOpen("MemTIFF", &iss);
// ...
此外,对于 PNG,您现在可以遵循 already posted article,因为 std::istringstream
的类型为 std::istream
。
请注意,此解决方案涉及将文件数据完全加载到内存中。
我正在尝试使用 libpng 从中读取 png Qt 资源。问题:class 正在阅读 应该不有Qt的任何依赖性。
第一步,阅读http://www.piko3d.net/tutorials/libpng-tutorial-loading-png-files-from-streams/#CustomRead我已经成功写了一个函数
read_png(istream& in)
我也成功传递了一个普通的旧 ifstream
ifstream in("abs_path_to_png/icon.png");
到read_png(..)并成功读取png。但是如何获得 来自 Qt 资源的(最好是独立于平台的)istream?表现 不是什么大问题所以我最初想出了
bool Io_Qt::get_istringstream_from_QFile(QFile& qfile, istringstream& iss)
{
// [.. Some checking for existence and the file being open ..]
QString qs(qfile.readAll());
iss.str(qs.toStdString());
// I also tried: QByteArray arr(qfile.readAll()); iss.str(arr.data());
return qfile.isOpen();
}
// Someplace else iss and qfile are created like this:
istringstream iss(std::stringstream::in | std::stringstream::binary);
QFile qfile(":/res/icon.png");
qfile.open(QIODevice::ReadOnly);
这实际上产生了一个问题,即乍一看,看起来不错,当说
cout << "'" << iss.str().c_str() << "'" << endl;
我明白了
'�PNG
'
虽然似乎存在一些空白问题。对于
ifstream in("abs_path_to_png/icon.png");
char c;
cout << "'";
for (int j=0;j<8;j++)
{
in >> c;
cout << c;
}
cout << "'" << endl;
产量
'�PNG'
虽然后者有效,但前一个变体最终导致 libpng 检查函数 png_sig_cmp(..) 拒绝我的 png 为无效。我的第一反应是 "binary"。然而:
- istringstream iss(std::stringstream::in | std::stringstream::binary);感觉不错。
- QIODevice::ReadOnly 似乎没有二进制伙伴。
你看到我错过了什么了吗?
您正在处理流,就像处理带有词法提取运算符的文本数据一样。查看 ios::binary
以及适用于二进制流的 read
和 write
方法。
我会完全放弃 operator<<
和 operator>>
以支持 read
和 write
。使用 ostream::write
写入从 QIODevice::readAll()
返回的字节数组数据以将其内容传输到您的临时字符串流,例如,并在您的测试中使用 ostream::read
来验证其内容。
确保正确传输的一个很好的测试用例是编写一个测试,从 QFile 读取内容,使用 ostream::write
将其传输到二进制输出文件流(ofstream
),然后尝试用图像软件加载它,看看是否可以。然后将您的文件流与字符串流交换,并在您工作时将其传递给 libpng
。
正如艾克所说,这似乎确实是关于两者之间的差异 以文本为中心的运算符“>>”、“<<”和类似“.str(..)”的东西 以二进制为中心的命令,如“.read”和“.write”。加上它是 关于正确初始化流。当我终于得到程序 做我想做的福音是这样的:
首先,我在 QFile 旁边使用了一个普通的字符串流:
// Explicitly setting flags should at least contain ::in and ::out
// stringstream ss(std::stringstream::in | std::stringstream::out | std::stringstream::binary)
// However, the default constructor is perfectly fine.
stringstream ss;
QFile qfile(":/res/icon.png");
qfile.open(QIODevice::ReadOnly);
这是我传递给我的函数,现在看起来像这样:
bool Io_Qt::get_stringstream_from_QFile(QFile& qfile, stringstream& ss)
{
// [.. some sanity checks..]
QDataStream in(&qfile);
uint len = qfile.size();
char* c = (char*)malloc(len*sizeof(char));
in.readRawData(c,len);
ss.write(c,len);
free (c);
return true;
}
此流已填充,并且大小合适。特别是从 .write(..) 写入所需数量的字符,无论 数据中有多少个零。我最大的问题是 我不愿意同时拥有 std::stringstream::in 和 std::stringstream::out同时激活因为 组合对我来说似乎有些古怪。然而两者都是需要的。 但是,我发现我可以跳过std::stringstream::binary。 但是因为它似乎没有任何伤害我喜欢 保持好运。不过,请随意评论这个迷信! :-)
更干净、更少 C 风格、更多 Qt/C++ 风格的版本可以是:
QFile file(filePath);
file.open(QIODevice::ReadOnly);
QByteArray data = file.readAll();
std::istringstream iss(data.toStdString());
现在使用 iss
,在我的例子中,这是用于 libTIFF:
TIFF* tif = TIFFStreamOpen("MemTIFF", &iss);
// ...
此外,对于 PNG,您现在可以遵循 already posted article,因为 std::istringstream
的类型为 std::istream
。
请注意,此解决方案涉及将文件数据完全加载到内存中。