使用C++读取tiff图像

4

我正在尝试从一个tiff图像文件中获取信息。Endian的输出是正确的,但其他的都是错误的。tiff文件的前8个字节为:

4d  4d  00  2a  00  02  03  60

我收到的magicno是10752,也就是十六进制中的2A00。但我应该读取第三和第四个字节,这应该是002a。请帮帮我!以下是我的代码:
#include <iostream>
#include <fstream>


using namespace std;

int main()
{
    char buffer[3];

    short magicno;
    int ifdaddress;
    short ifdcount;


    ifstream imfile;
    imfile.open("pooh.tif",ios::binary);

    imfile.seekg(0,ios::beg);

    imfile.read(buffer,2);
    imfile.read((char*)&magicno, 2);
    imfile.read((char*)&ifdaddress, 4);

    imfile.seekg(ifdaddress, ios::beg);
    imfile.read((char*)&ifdcount, 2);

    imfile.close();

    buffer[2]='\0';


    cout<<"Endian: "<<buffer<<endl;
    cout<<"Magic: "<<magicno<<endl;
    cout<<"IFD Address: "<<ifdaddress<<endl;
    cout<<"IFD CountL "<<ifdcount<<endl;

    return 0;

}

我的输出结果是:

Endian: MM
Magic: 10752
IFD Address: 1610809856
IFD CountL 0
1个回答

1
你正确地读取了字节序标记,但你没有对其进行处理。来自Adobe的“TIFF 6”:

字节0-1:
文件中使用的字节顺序。合法值为:
“II”(4949.H)
“MM”(4D4D.H)
在“II”格式中,无论是16位还是32位整数,字节顺序始终从最不重要的字节到最重要的字节。这称为小端字节序。在“MM”格式中,无论是16位还是32位整数,字节顺序始终从最重要的字节到最不重要的字节。这称为大端字节序。
(https://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf)

您需要两组例程来从TIFF文件中读取短整数(以及读取更长的整数类型):一个读取Motorola(“MM”)大端数字,另一个读取Intel(“II”)小端数字。

作为现状,当你试图在本地读取大端序数时,你必须是一个小端序系统。
正确读取一个字的代码可以非常简单:
unsigned char d1,d2;
imfile.read (&d1,1);
imfile.read (&d2,1);
if (magicno == 0x4949)
   word = d1 + (d2<<8);
else
   word = (d1<<8)+d2;

未经测试,但是一般的想法应该很明确。最好将其制作成一个函数,因为您需要类似的设置来处理“LONG”数据类型,而这又是“RATIONAL”数据类型所需的。对于TIFF文件,最终您可能需要一个通用的“read_data”函数,它首先检查文件中存储的数据类型,然后调用正确的例程。

非常感谢!现在我知道我的问题是什么了。我还有一个问题。如果我从tiff文件中读取的是十六进制,为什么我打印出来的是十进制数? - user2817869
1
@user2817869 << 是位运算符之一。如果你正在编写这样的代码,你需要详细了解它们。一个好的起点是:http://www.cprogramming.com/tutorial/bitwise_operators.html - Ixrec
@user2817869:但是其实并没有勺子,我指的是“十六进制”。 “十六进制”只是某个(抽象)数字的表示,就像符号10一样。你正在读取字节,它们的值可以从0到255,并且可以被解释为-128到+127,或者作为ASCII字符。这些字节本身并不是“十六进制”或“十进制”的。 - Jongware
我曾经尝试过使用 a 对四个字节编码来执行 word = (a<<24)+(b<<16)+(c<<8)+d;,但是失败了... 我该如何改变它? - user2817869
@user2817869:嗯,你得到的结果有什么问题吗?你已经正确地使用大端序列来表示长数字的想法了。你需要确保中间值abcd都是无符号的。如果你还遇到问题,请像这个问题一样发布一个新的问题并附上你的结果。 - Jongware
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接