不幸的是,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]”的段中,其中“n”是某个数字,对于 JPEG 解码器来说意味着特殊的东西。只查找 a 应该就足够了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()
实现中发现的结构。