我正在尝试了解jpeg文件的EXIF标题部分(十六进制)以及如何理解它以便我可以提取数据,特别是GPS信息。无论好坏,我使用VB.Net 2008(对不起,这是我现在能掌握的)。我已经将jpg的第一个64K提取到字节数组,并且对数据的排列方式有一个模糊的概念。使用版本2.2和2.3的EXIF规范文档,我看到有些标记应该与文件中的实际字节序列相对应。我看到有一个“GPS IFD”,其值为8825(十六进制)。我在文件中搜索十六进制字符串8825(我理解为两个字节88和25)然后我相信8825之后有一个字节序列。我怀疑那些后续字节表示文件中的位置,偏移方式,GPS数据将被定位。例如,我有以下十六进制字节,从88开始25:88 25 00 04 00 00 00 01 00 00 05 9A 00 00 07 14.我要查找的字符串是否超过16个字节?我得到的印象是,在这一系列数据中,它应该告诉我在哪里可以找到文件中的实际GPS数据。
在页面的中间看http://search.cpan.org/~bettelli/Image-MetaData-JPEG-0.153/lib/Image/MetaData/JPEG/Structures.pod#Exif_and_DCT,它谈到“每个IFD块都是一个结构化的记录序列,在Exif术语中称为互操作性数组。第0个IFD的开头由'IFD0_Pointer'值给出。 IFD的结构如下:“
那么,什么是IFD0_Pointer?它与偏移量有关吗?我假设一个偏移量是从一个起点开始的那么多字节。如果这是真的,那个起点在哪里?
感谢您的回复。
戴尔
答案 0 :(得分:16)
我建议你阅读Exif Specification(PDF);这很清楚,很容易理解。对于简短的入门,这里是我写的article的摘要:
JPEG / Exif文件以图像标记(SOI)的开头开始。 SOI由两个魔术字节0xFF 0xD8
组成,将文件标识为JPEG文件。在SOI之后,有许多应用标记部分(APP0,APP1,APP2,APP3,......)通常包括元数据。
每个APPn部分都以标记开头。对于APP0部分,标记为0xFF 0xE0
,对于APP1部分0xFF 0xE1
,依此类推。标记字节后跟两个字节的大小(不包括标记,包括大小字节)。长度字段后跟可变大小的应用程序数据。 APPn部分是顺序的,因此您可以跳过整个部分(使用部分大小),直到找到您感兴趣的部分.APPE部分的内容会有所不同,以下内容仅适用于Exif APP1部分
Exif元数据存储在 APP1部分中(可能有多个APP1部分)。 Exif APP1部分中的应用程序数据由Exif标记0x45 0x78 0x69 0x66 0x00 0x00
("Exif\0\0"
),TIFF标题和许多图像文件目录(IFD)部分组成。
TIFF标头包含有关IFD部分的字节顺序和指向第0个IFD的指针的信息。如果字节顺序为little-endian,则前两个字节为0x49 0x49
(英语为II
,对于big-endian,则为0x4D 0x4D
(摩托罗拉为MM
)。以下两个字节是魔术字节0x00 0x2A
(42
;))。以下四个重要字节将告诉您从TIFF标头开始到第0个IFD的偏移量。
重要事项:JPEG文件本身(您到目前为止所阅读的内容)将始终采用大端格式。但是,IFD子节的字节顺序可能不同,需要转换(你知道上面TIFF标题的字节顺序)。
一旦你走到这一步,你有指向第0个IFD部分的指针,你就可以阅读实际的元数据了。其余的IFD在不同的地方被引用。在第0个IFD字段中给出了Exif IFD和GPS IFD的偏移量。在第0个IFD字段之后给出第一个IFD的偏移量。互操作性IFD的偏移量在Exif IFD中给出。
IFD只是元数据字段的顺序记录。字段计数在IFD的前两个字节中给出。字段计数后面是12字节字段。在字段之后,从TIFF标头的开始到第一个IFD的开始有一个4字节的偏移。该值仅对第0个IFD有意义。在此之后,有IFD数据部分。
字段是IFD部分的12字节子部分。每个字段的前两个字节给出Exif标准中定义的标签ID。接下来的两个字节给出了字段数据的类型。 1
为byte
,2
为ascii
,3
short
为uint16
,{{1} } 4
(long
)等。检查Exif规范以获取完整列表。
以下四个字节可能有点令人困惑。对于字节数组(uint32
和ascii
),给出了数组的字节长度。例如,对于Ascii字符串:undefined types
,计数将为5,包括空终止符。对于其他类型,这是场组件的数量(例如,4个短裤,3个有效合理)。
计数之后,我们有4字节的字段值。但是,如果字段数据的长度超过4个字节,则它将存储在IFD数据部分中。在这种情况下,该值将是从TIFF标题的开头到字段数据的开头的偏移量。例如,对于"Exif"
(long
,4个字节),这将是字段值。对于uint32
(rational
,8个字节),这将是8字节字段数据的偏移量。
这基本上是如何在JPEG / Exif文件中排列元数据。需要记住一些注意事项(记得根据需要转换字节顺序,偏移是从TIFF标题的开头,跳转到数据部分以读取长字段,......)但格式很容易阅读。以下是JPEG / Exif文件的颜色编码HEX视图。蓝色块表示SOI,橙色表示TIFF标题,绿色表示IFD大小和偏移字节,浅紫色块表示IFD字段,深紫色块表示字段数据。
答案 1 :(得分:0)
这是我编写的用于修改exif标题的php脚本。
<?php
$full_image_string=file_get_contents("torby.jpg");
$filename="torby.jpg";
if (isset($_REQUEST['filename'])){$filename=$_REQUEST['filename'];}
if (array_key_exists('file', $_REQUEST)) {
$thumb_image = exif_thumbnail($_REQUEST['file'], $width, $height, $type);
} else {
$thumb_image = exif_thumbnail($filename, $width, $height, $type);
}
if ($thumb_image!==false) {
echo $thumb_image;
$thumblen=strlen($thumb_image);
echo substr_count($full_image_string,$thumb_image);
$filler=str_pad("%%%THUMB%%%", $thumblen);
$full_image_string=str_replace($thumb_image,$filler,$full_image_string);
file_put_contents("torby.jpg",$full_image_string);
exit;
} else {
// no thumbnail available, handle the error here
echo 'No thumbnail available';
}
?>