这是我的第一篇文章,因为我到目前为止使用了搜索功能。但现在我在以下问题上浪费了一整天:
我录制了一个12位(写为16位)灰度视频,并将其直接写入二进制流文件(无标题等)。
现在的任务是读取文件并将每帧输出为16位pgm。
以下剪辑说明了我尝试过的内容。输出是一个有效的pgm,但它上面有“白噪声”。
...
imageBufferShort = new short[imageWidth*imageHeight* sizeof(short)];
...
streamFileHandle.read(reinterpret_cast<char*>(imageBufferShort),2*imageWidth*imageHeight); //double amount because 8bit chars!
// As .read only takes chars, I thought, that I just read the double amount of char-bytes and when it is interpreted as short (=16bit) everything is ok?!?
...now the pgm output:
std::ofstream f_hnd(fileName,std::ios_base::out |std::ios_base::binary |std::ios_base::trunc);
// write simple header
f_hnd.write("P5\n",3);
f_hnd << imageWidth << " " << imageHeight << "\n4095\n"; //4095 should tell the pgm to use 2 bytes for each pixel
f_hnd.write(reinterpret_cast<char*>(imageBufferShort),2*imageWidth*imageHeight);
f_hnd.close();
同样,该文件已生成并可查看但包含垃圾。最初的猜测好吗?阅读2个“字符”并将它们作为一个“短”处理?我也在每行之后删除一个空格,但这没有任何改变,所以我决定发布这个更短的代码。
感谢您的帮助!
答案 0 :(得分:1)
正如@Domi和@JoeZ所指出的那样:你的结尾可能搞砸了。意思是,你的字节顺序是错误的。
要解决您的问题,您必须迭代每个像素并交换它的字节,然后再将其写回文件。
答案 1 :(得分:0)
解决了问题。非常感谢你们。 Endianess确实是问题所在。解决方案如下:
f_hnd << "P5" << " " << imDimensions.GetWidth() << " " << imDimensions.GetHeight() << " " << "4095\n";
// convert imageBufferShort to Big-Endian format
unsigned short imageBufferShortBigEndian[imDimensions.GetWidth()*imDimensions.GetHeight()];
for (int k=0 ; k<imDimensions.GetWidth()*imDimensions.GetHeight() ; k++)
{
imageBufferShortBigEndian[k] = ( (imageBufferShort[k] << 8) | (imageBufferShort[k] >> 8) );
}
f_hnd.write(reinterpret_cast<char*>(imageBufferShortBigEndian),2*imDimensions.GetWidth()*imDimensions.GetHeight());
f_hnd.close();
imageBufferShort还有一个无符号的短数组。如果使用了带符号的类型,则bithift-conversion会变得更加困难。
再次感谢!