很不幸,对于JPEG格式来说,这似乎并不简单。你需要查看命令行工具jhead
的源代码,它提供了相关信息。在查看源代码时,你会看到ReadJpegSections
函数。该函数会扫描JPEG文件中包含的所有段以提取所需信息。处理带有SOFn
标记的帧时可以获得图像的宽度和高度。
我发现这个源代码是公共领域,所以我会展示获取图像信息的代码片段:
static int Get16m(const void * Short)
{
return (((uchar *)Short)[0] << 8) | ((uchar *)Short)[1];
}
static void process_SOFn (const uchar * Data, int marker)
{
int data_precision, num_components;
data_precision = Data[2];
ImageInfo.Height = Get16m(Data+3);
ImageInfo.Width = Get16m(Data+5);
从源代码来看,我清楚地知道这里没有单独的“标头”包含这些信息。你需要扫描JPEG文件,解析每个段落,直到找到你想要的包含所需信息的段落。这在维基百科文章中有描述:
JPEG图像由一系列段落组成,每个段落以一个标记开始,每个标记都以0xFF字节开头,后跟一个指示它是什么类型标记的字节。一些标记只由这两个字节组成;其他标记后面还跟着两个字节,表示跟随其后的标记特定有效载荷数据的长度。
JPEG文件由一系列段落组成:
SEGMENT_0
SEGMENT_1
SEGMENT_2
...
每个段落都以2个字节的标记开头。第一个字节是0xFF
,第二个字节确定段落类型。然后将段落长度进行编码。在段落内部是特定于该段落类型的数据。
图像的宽度和高度可以在类型为SOFn
的段落中找到,“n”是对JPEG解码器有特殊意义的某个数字。只需要寻找SOF0
段落即可,其字节指示为0xC0
。一旦找到这个段落,就可以对其进行解码以找到图像的高度和宽度。
因此,要实现你想要的程序结构应该如下:
file_data = the data in the file
data = &file_data[0]
while (data not at end of file_data)
segment_type = decoded JPEG segment type at data
if (type != SOF0)
data += byte length for segment_type
continue
else
get image height and width from segment
return
这本质上是在Michael Petrov的get_jpeg_size()
实现中发现的结构。
jpeg文件
。 - Lion King