从JFIF/EXIF(JPEG)头获取实际图像分辨率?

4

我已经创建了一个C++结构体,用于读取和验证JFIF文件格式的头部。 该结构如下所示...

#pragma pack(1)
typedef struct _JFIF_Header
{
    WORD SOIMarker;         // start of image marker
    WORD APP0_Marker;       // Application use marker
    WORD APP0_Length;       // Length of APP0 field
    BYTE Identifier[5];     // zero terminating string "JFIF",X'4A', X'46', X'49', X'46', X'00'
    BYTE Version[2];        // X'01',X'02'
    BYTE Units;             // units = 0:no units ;; units = 1:X and Y are dots per inch ;; units = 2:X and Y are dots per cm
    WORD XDensity;          // horizontal pixel density
    WORD YDensity;          // vertical pixel density
    BYTE XThumbnail;        // Thumbnail horizontal pixel density
    BYTE YThumbnail;        // Thumbnail vertical pixel density
}JFIFHeader;

已经从原始磁盘扇区中读取数据并将这些字节复制到JFIFHeader结构中,一切正常。

现在的问题是,保存在XDensityYDensity变量中的值非常高(我在Hex编辑器中读取了一个图像,X:24576,Y:24576),这个值不能是图像的实际宽度和高度。

Units的值为0x01,即单位为“每英寸像素数”。

如何从这些值中获取实际图像分辨率1024x826?如果这不是正确的方法,请给我任何其他替代方案。


2
24567 = 0x6000。交换两个字节,因为你以错误的顺序读取它们 = 0x0060 = 96。96 dpi 是一个非常常见的值。不要编写自己的 JPEG 解码器。 - Hans Passant
是的,这就是我想的。刚看到一个示例代码。谢谢。 - Hemendra Sharma
1个回答

8

您可以定位JPEG的SOF0标记(0xC0),其后跟16位长度,然后是每像素位数(8位),高度(16位),宽度(16位)和组件计数(8位)。所有值都按网络字节顺序排列。

enter image description here

图像大小为0x1C2乘以0x1C2像素(450x450)。


1
请注意,这可能会获取缩略图的大小。甚至是实际图像“SOF0”块之前的块中的垃圾数据。 - ratchet freak
@ratchetfreak:抓取错误的东西怎么可能呢?如果你直接搜索0xFF 0xC0?如果你正确跳过之前的段落(逐个读取并根据其长度跳过它们),那应该完全没问题,对吧? - DrP3pp3r

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