exif_read_data

(PHP 4 >= 4.2.0,PHP 5,PHP 7,PHP 8)

exif_read_data从图像文件读取 EXIF 头部

描述

exif_read_data(
    资源|字符串 $file,
    ?字符串 $required_sections = null,
    布尔值 $as_arrays = false,
    布尔值 $read_thumbnail = false
): 数组|false

exif_read_data() 从图像文件读取 EXIF 头部。这样,您可以读取数码相机生成的元数据。

数码相机生成的 JPEG/TIFF 图像中通常包含 EXIF 头部,但不幸的是,每家数码相机制造商对图像的标记方式都有不同的想法,因此您不能总是依赖于特定 Exif 头部的存在。

HeightWidth 的计算方式与 getimagesize() 相同,因此它们的数值不应是返回的任何头部的一部分。此外,html 是一个高度/宽度文本字符串,用于在普通 HTML 中使用。

当 Exif 头部包含版权注释时,它本身可以包含两个值。由于 Exif 2.10 标准中的解决方案不一致,COMPUTED 部分将返回两个条目 Copyright.PhotographerCopyright.Editor,而 IFD0 部分包含包含 NULL 字符的字节数组,该字符用于分隔这两个条目。或者,如果数据类型错误(Exif 的正常行为),则仅返回第一个条目。 COMPUTED 还将包含条目 Copyright,它或者是原始版权字符串,或者是照片和编辑版权的逗号分隔列表。

标签 UserComment 与版权标签存在相同的问题。它可以存储两个值。第一个是使用的编码,第二个是值本身。如果是这样,则 IFD 部分只包含编码或字节数组。 COMPUTED 部分将把这两个值存储在 UserCommentEncodingUserComment 条目中。 UserComment 条目在这两种情况下都可用,因此应优先使用它,而不是 IFD0 部分中的值。

exif_read_data() 还根据 EXIF 规范 (» http://exif.org/Exif2-2.PDF,第 20 页) 验证 EXIF 数据标签。

参数

file

图像文件的路径。这可以是文件的路径(流包装器也像往常一样支持),也可以是流 资源

required_sections

是一个逗号分隔的节列表,这些节需要存在于文件中才能生成一个结果 数组。如果找不到任何请求的节,则返回值为 false

FILE FileName、FileSize、FileDateTime、SectionsFound
COMPUTED html、Width、Height、IsColor,以及更多可用的信息。Height 和 Width 的计算方式与 getimagesize() 相同,因此它们的数值不应是返回的任何头部的一部分。此外,html 是一个高度/宽度文本字符串,用于在普通 HTML 中使用。
ANY_TAG 任何具有标签的信息,例如 IFD0EXIF 等。
IFD0 IFD0 的所有标记数据。在普通图像文件中,这包含图像大小等信息。
THUMBNAIL 如果文件包含第二个 IFD,则应该包含缩略图。有关嵌入式缩略图的所有标记信息都存储在此部分中。
COMMENT JPEG 图像的注释头部。
EXIF EXIF 部分是 IFD0 的子部分。它包含有关图像的更多详细信息。这些条目中的大多数与数码相机相关。

as_arrays

指定每个节是否成为一个数组。 required_sections COMPUTEDTHUMBNAILCOMMENT 总是成为数组,因为它们可能包含名称与其他节冲突的值。

read_thumbnail

当设置为 true 时,将读取缩略图本身。否则,只读取标记数据。

返回值

它返回一个关联的 数组,其中数组索引是头部名称,数组值是与这些头部关联的值。如果无法返回任何数据,则 exif_read_data() 将返回 false

错误/异常

对于不支持的标签或其他潜在的错误情况,可能会引发级别为 E_WARNING 和/或 E_NOTICE 的错误,但该函数仍会尝试读取所有可理解的信息。

变更日志

版本 描述
8.0.0 required_sections 现在可以为空。
7.2.0 file 参数现在同时支持本地文件和流资源。
7.2.0

添加了对以下 EXIF 格式的支持

  • 三星
  • DJI
  • 松下
  • 索尼
  • 宾得
  • 美能达
  • Sigma/Foveon
  • 爱克发
  • 京瓷
  • 理光
  • 爱普生

示例

示例 #1 exif_read_data() 示例

<?php
echo "test1.jpg:<br />\n";
$exif = exif_read_data('tests/test1.jpg', 'IFD0');
echo
$exif===false ? "未找到头部数据。<br />\n" : "图像包含头部<br />\n";

$exif = exif_read_data('tests/test2.jpg', 0, true);
echo
"test2.jpg:<br />\n";
foreach (
$exif as $key => $section) {
foreach (
$section as $name => $val) {
echo
"$key.$name: $val<br />\n";
}
}
?>

第一个调用失败,因为图像没有头部信息。

上面的示例将输出类似于以下内容

test1.jpg:
No header data found.
test2.jpg:
FILE.FileName: test2.jpg
FILE.FileDateTime: 1017666176
FILE.FileSize: 1240
FILE.FileType: 2
FILE.SectionsFound: ANY_TAG, IFD0, THUMBNAIL, COMMENT
COMPUTED.html: width="1" height="1"
COMPUTED.Height: 1
COMPUTED.Width: 1
COMPUTED.IsColor: 1
COMPUTED.ByteOrderMotorola: 1
COMPUTED.UserComment: Exif test image.
COMPUTED.UserCommentEncoding: ASCII
COMPUTED.Copyright: Photo (c) M.Boerger, Edited by M.Boerger.
COMPUTED.Copyright.Photographer: Photo (c) M.Boerger
COMPUTED.Copyright.Editor: Edited by M.Boerger.
IFD0.Copyright: Photo (c) M.Boerger
IFD0.UserComment: ASCII
THUMBNAIL.JPEGInterchangeFormat: 134
THUMBNAIL.JPEGInterchangeFormatLength: 523
COMMENT.0: Comment #1.
COMMENT.1: Comment #2.
COMMENT.2: Comment #3end
THUMBNAIL.JPEGInterchangeFormat: 134
THUMBNAIL.Thumbnail.Height: 1
THUMBNAIL.Thumbnail.Height: 1

示例 #2 exif_read_data(),从 PHP 7.2.0 开始支持流

<?php
// 以二进制模式打开文件
$fp = fopen('/path/to/image.jpg', 'rb');

if (!
$fp) {
echo
'错误: 无法打开图像进行读取';
exit;
}

// 尝试读取 EXIF 头信息
$headers = exif_read_data($fp);

if (!
$headers) {
echo
'错误: 无法读取 EXIF 头信息';
exit;
}

// 打印 'COMPUTED' 头信息
echo 'EXIF 头信息:' . PHP_EOL;

foreach (
$headers['COMPUTED'] as $header => $value) {
printf(' %s => %s%s', $header, $value, PHP_EOL);
}
?>

上面的示例将输出类似于以下内容

EXIF Headers:
 Height => 576
 Width => 1024
 IsColor => 1
 ByteOrderMotorola => 0
 ApertureFNumber => f/5.6
 UserComment =>
 UserCommentEncoding => UNDEFINED
 Copyright => Denis
 Thumbnail.FileType => 2
 Thumbnail.MimeType => image/jpeg

注释

注意:

如果启用了 mbstring,exif 将尝试处理 Unicode 并根据 exif.decode_unicode_motorolaexif.decode_unicode_intel 指定的字符集进行选择。exif 扩展程序不会尝试自行找出编码,用户需要在调用 exif_read_data() 之前,通过设置这两个 ini 指令之一来正确指定用于解码的编码。

注意:

如果使用 file 参数向此函数传递一个流,那么这个流必须是可以查找的。请注意,此函数返回后,文件指针位置不会改变。

参见

添加注释

用户贡献的注释 19 个注释

83
chadsmith729 at gmail dot com
11 年前
当 Apple 为 iOS6 发布了新的更新后,它为 iPad、iPod 和 iPhone 提供了通过 Safari 从设备上传文件的功能。显然,这将开启一系列实现,这些实现以前是无法实现的。

问题是,当上传照片时,它将取决于照片拍摄时“按钮”的位置。假设您的 iPhone 按钮在顶部,您拍摄了一张照片。当照片上传到服务器时,它可能是“倒置”的。

以下代码将确保所有上传的照片在上传后都以正确的方向显示。
<?php
$image
= imagecreatefromstring(file_get_contents($_FILES['image_upload']['tmp_name']));
$exif = exif_read_data($_FILES['image_upload']['tmp_name']);
if(!empty(
$exif['Orientation'])) {
switch(
$exif['Orientation']) {
case
8:
$image = imagerotate($image,90,0);
break;
case
3:
$image = imagerotate($image,180,0);
break;
case
6:
$image = imagerotate($image,-90,0);
break;
}
}
// $image 现在包含一个方向正确的图像资源
?>

如何处理图像资源完全由您决定。

我希望这可以帮助您识别和调整从 iPad、iPhone 或 iPod 上传的任何图像。照片的方向是了解如何正确旋转它的关键。
4
Tim
4 年前
以下代码
<?php
$data
= exif_read_data('foo.jpg');
var_dump($data['Keywords']);
?>
输出 string(15) "???????????????"

添加
<?php
ini_set
('exif.decode_unicode_motorola', 'UCS-2LE');
?>
在调用 exif_red_data 之前,会输出
string(15) "landscape;;field"
6
darkain at darkain dot com
16 年前
我想要一些快速简便的函数来计算快门速度和光圈值。我到处都找不到,所以我自己写了一些。我做了一些研究

<?php
function exif_get_float($value) {
$pos = strpos($value, '/');
if (
$pos === false) return (float) $value;
$a = (float) substr($value, 0, $pos);
$b = (float) substr($value, $pos+1);
return (
$b == 0) ? ($a) : ($a / $b);
}

function
exif_get_shutter(&$exif) {
if (!isset(
$exif['ShutterSpeedValue'])) return false;
$apex = exif_get_float($exif['ShutterSpeedValue']);
$shutter = pow(2, -$apex);
if (
$shutter == 0) return false;
if (
$shutter >= 1) return round($shutter) . 's';
return
'1/' . round(1 / $shutter) . 's';
}

function
exif_get_fstop(&$exif) {
if (!isset(
$exif['ApertureValue'])) return false;
$apex = exif_get_float($exif['ApertureValue']);
$fstop = pow(2, $apex/2);
if (
$fstop == 0) return false;
return
'f/' . round($fstop,1);
}
?>
2
omerg at lucidcode dot com dot tr
5 年前
提供的用于显示 exif 数组内容的示例在最新版本中不起作用,因为并非所有条目值都是数组类型。

这是一个可选的 echo 循环

<?php
echo "test1.jpg:<br />\n";
$exif = exif_read_data('tests/test1.jpg', 'IFD0');
echo
$exif===false ? "没有找到头数据。<br />\n" : "图像包含头信息<br />\n";

$exif = exif_read_data('tests/test2.jpg', 0, true);
echo
"test2.jpg:<br />\n";
foreach (
$exif as $key => $section) {

if (!
is_array ($section)) {
echo
"$key: $section<br />\n";
} else {
foreach (
$section as $name => $val) {
echo
"$key.$name: $val<br />\n";
}
}

}
?>
8
drpain at webster dot org dot za
12 年前
请注意,使用 GD 和大多数图像处理脚本或应用程序调整图像大小会丢失 EXIF 信息。我的解决方法是在调整图像大小之前将此信息存储在 MySQL 中。

<?php

// 此函数用于确定特定图像的相机详细信息。它返回一个包含参数的数组。
function cameraUsed($imagePath) {

// 检查变量是否已设置,并且文件本身是否存在,然后再继续
if ((isset($imagePath)) and (file_exists($imagePath))) {

// 有两个数组包含我们想要的信息,所以最好同时声明它们
$exif_ifd0 = read_exif_data($imagePath ,'IFD0' ,0);
$exif_exif = read_exif_data($imagePath ,'EXIF' ,0);

// 错误控制
$notFound = "不可用";

// 制造
if (@array_key_exists('Make', $exif_ifd0)) {
$camMake = $exif_ifd0['Make'];
} else {
$camMake = $notFound; }

// 型号
if (@array_key_exists('Model', $exif_ifd0)) {
$camModel = $exif_ifd0['Model'];
} else {
$camModel = $notFound; }

// 曝光
if (@array_key_exists('ExposureTime', $exif_ifd0)) {
$camExposure = $exif_ifd0['ExposureTime'];
} else {
$camExposure = $notFound; }

// 光圈
if (@array_key_exists('ApertureFNumber', $exif_ifd0['COMPUTED'])) {
$camAperture = $exif_ifd0['COMPUTED']['ApertureFNumber'];
} else {
$camAperture = $notFound; }

// 日期
if (@array_key_exists('DateTime', $exif_ifd0)) {
$camDate = $exif_ifd0['DateTime'];
} else {
$camDate = $notFound; }

// ISO
if (@array_key_exists('ISOSpeedRatings',$exif_exif)) {
$camIso = $exif_exif['ISOSpeedRatings'];
} else {
$camIso = $notFound; }

$return = array();
$return['make'] = $camMake;
$return['model'] = $camModel;
$return['exposure'] = $camExposure;
$return['aperture'] = $camAperture;
$return['date'] = $camDate;
$return['iso'] = $camIso;
return
$return;

} else {
return
false;
}
}

?>

以下是一个使用示例

<?php

$camera
= cameraUsed("/img/myphoto.jpg");
echo
"使用的相机: " . $camera['make'] . " " . $camera['model'] . "<br />";
echo
"曝光时间: " . $camera['exposure'] . "<br />";
echo
"光圈: " . $camera['aperture'] . "<br />";
echo
"ISO: " . $camera['iso'] . "<br />";
echo
"拍摄日期: " . $camera['date'] . "<br />";

?>

将显示以下内容,具体取决于数据

使用的相机: SONY DSC-S930
曝光时间: 1/400
光圈: f/4.3
ISO: 100
拍摄日期: 2010:12:10 18:18:45

如果图像已调整大小并且信息不再可用,那么使用相同的代码回显时,您应该收到以下内容

使用的相机: 不可用
曝光时间: 不可用
光圈: 不可用
ISO: 不可用
拍摄日期: 不可用

一些相机无法捕获所有信息,例如,黑莓手机不会记录光圈或 ISO,您将获得这些字段的“不可用”。

希望您觉得这有帮助。
3
mafo at mafo removethis dot sk
17 年前
一些相机(大多数高端型号)具有位置传感器(陀螺仪?)并且拍摄位置信息写入 EXIF,以下是一个自动旋转图像的简单脚本

<?php
$exif
= exif_read_data($filename);
$ort = $exif['IFD0']['Orientation'];
switch(
$ort)
{
case
1: // 什么也不做
break;

case
2: // 水平翻转
$image->flipImage($public,1);
break;

case
3: // 顺时针旋转 180 度
$image->rotateImage($public,180);
break;

case
4: // 垂直翻转
$image->flipImage($public,2);
break;

case
5: // 垂直翻转 + 顺时针旋转 90 度
$image->flipImage($public, 2);
$image->rotateImage($public, -90);
break;

case
6: // 顺时针旋转 90 度
$image->rotateImage($public, -90);
break;

case
7: // 水平翻转 + 顺时针旋转 90 度
$image->flipImage($public,1);
$image->rotateImage($public, -90);
break;

case
8: // 逆时针旋转 90 度
$image->rotateImage($public, 90);
break;
}

?>

$image->rotateImage() 是受 https://php.net/manual/en/function.imagerotate.php 例子的启发
$image->flipImage() 是受 https://php.net/manual/en/function.imagecopy.php#42803 的启发(感谢您)
0
dbareis at gmail dot com
1 个月前
Windows 字段位于 "WINXP" 部分(格式我并不知道),但它们也出现在其他地方,包括 "comments" 和 "subject",以 null 结尾的 "UTF-16LE" 格式,这段代码对我有用。

...
$PhotoInfo->Comments = GetPhotoValueWindows16Bit($IDFO, 'Comments');
$PhotoInfo->Subject = GetPhotoValueWindows16Bit($IDFO, 'Subject');

function GetPhotoValueWindows16Bit(&$Array, $Index)
{
$Value16 = GetPhotoValue($Array, $Index);
if ($Value16 === null)
$R = null;
else
{
$R = iconv('UTF-16LE', 'UTF-8', $Value16); // 仍然以 null 字节结尾
$R = str_replace("\x00", '', $R); // 删除尾部的 null(但要处理任何 null)。
}
return $R;
}
0
service at tianex dot com
7 个月前
这个错误发生在获取 jpeg 文件 exif 信息时

exif_read_data(): 从文件读取错误: got=x3FFA(=16378) != itemlen-2=x4325(=17189)
0
TNTcode
6 年前
<?php

// 根据相机中的 exif 数据自动旋转图像文件
// 如果指定了目标文件,则将其保存在那里,否则将其显示给用户
// 注意,当 exif 数据 Orientation = 1 时,跳过已经处于正常方向的图像

if(!function_exists("gd_auto_rotate")){
function
gd_auto_rotate($original_file, $destination_file=NULL){

$original_extension = strtolower(pathinfo($original_file, PATHINFO_EXTENSION));
if(isset(
$destination_file) and $destination_file!=''){
$destination_extension = strtolower(pathinfo($destination_file, PATHINFO_EXTENSION));
}

// 尝试通过 gd 自动旋转图像(如果需要)(在编辑之前)
// 通过 imagemagik,它有一个简单的选项
if(function_exists("exif_read_data")){

$exif_data = exif_read_data($original_file);
$exif_orientation = $exif_data['Orientation'];

// 值 1 = 正常 ?! 跳过它 ?!

if($exif_orientation=='3' or $exif_orientation=='6' or $exif_orientation=='8'){

$new_angle[3] = 180;
$new_angle[6] = -90;
$new_angle[8] = 90;

// 加载图像
if($original_extension == "jpg" or $original_extension == "jpeg"){
$original_image = imagecreatefromjpeg($original_file);
}
if(
$original_extension == "gif"){
$original_image = imagecreatefromgif($original_file);
}
if(
$original_extension == "png"){
$original_image = imagecreatefrompng($original_file);
}

$rotated_image = imagerotate($original_image, $new_angle[$exif_orientation], 0);

// 如果没有设置目标文件,则显示图像
if(!$destination_file){
header('Content-type: image/jpeg');
imagejpeg($rotated_image, NULL, 100);
}

// 如果给出了目标文件,则保存较小的图像文件
if($destination_extension == "jpg" or $destination_extension=="jpeg"){
imagejpeg($rotated_image, $destination_file,100);
}
if(
$destination_extension == "gif"){
imagegif($rotated_image, $destination_file);
}
if(
$destination_extension == "png"){
imagepng($rotated_image, $destination_file,9);
}

imagedestroy($original_image);
imagedestroy($rotated_image);

}
}
}
}

?>
0
b at asdflolinternet dot de
8 年前
当值(例如 exif[IFD0][Title])通过 Windows 右键单击属性进行编辑,然后使用 read_exif_data() 函数读取时,会出现 "S�o�m�e� �T�e�x�t��" 问题。
尝试

$exif_['IFD0']['Title']=mb_convert_encoding($exif_['IFD0']['Title'],"auto","byte2le");

适用于 UTF-8 等等。

//
// 输出所有可用的字符编码并在屏幕上打印
// foreach(mb_list_encodings() as $chr)
// {$test[$chr]=mb_convert_encoding($image[IFD0][Title],'auto',$chr);}
// exit(print_r($test));
//
0
Eion Robb
9 年前
我需要使用 exif_read_data() 读取方向标志,结果发现虚拟主机没有提供 exif 扩展供使用。相反,我编写了一个正则表达式,它作为替代方案效果很好。

<?php
$orientation
= 1;
if (
function_exists('exif_read_data')) {
$exif = exif_read_data($filename);
if (isset(
$exif['Orientation']))
$orientation = $exif['Orientation'];
} else if (
preg_match('@\x12\x01\x03\x00\x01\x00\x00\x00(.)\x00\x00\x00@', file_get_contents($filename), $matches)) {
$orientation = ord($matches[1]);
}
?>
0
Clive dot Moore at ma-design dot com
10 年前
跟进 darkain at darkain dot com 脚本,用于从 exif 数据中获取 ShutterSpeedValue...
@https://php.net/manual/en/function.exif-read-data.php

我发现 exif 数据中显示的 ShutterSppedValue 选项也可以是 ExposureTime。

此外,代码的编写方式会导致错误的返回值,因为返回值始终为 1,因此得到 1/1 秒。

以下为修正后的代码,或者是一个版本,它修正了最初开发 5 年后显然无法正常工作的问题。

以下是针对:: $exif[ExposureTime] 的更新版本

function exif_get_float($value) {
$pos = strpos($value, '/');
if ($pos === false) return (float) $value;
$a = (float) substr($value, 0, $pos);
$b = (float) substr($value, $pos+1);
return ($b == 0) ? ($a) : ($a / $b);
};

function exif_get_exposureTime(&$exif) {
if (!isset($exif['ExposureTime'])) return false;
$apex = exif_get_float($exif['ExposureTime']);
$shutter = 1/$apex;
// 曝光时间大于 1 秒:
if ($shutter <= 1) return round($apex) . ' 秒';

return '1/' . round(1 / $apex) . ' 秒';
};
0
hoangvu4000 at gmail dot com
11 年前
这是一个函数,用于调整图像大小,并且不旋转具有 exif 信息的图像

必须启用 PHP
extension=php_mbstring.dll
extension=php_exif.dll

<?php
function CreateThumbnail($pic,$thumb,$thumbwidth, $quality = 100)
{

$im1=ImageCreateFromJPEG($pic);

//if(function_exists("exif_read_data")){
$exif = exif_read_data($pic);
if(!empty(
$exif['Orientation'])) {
switch(
$exif['Orientation']) {
case
8:
$im1 = imagerotate($im1,90,0);
break;
case
3:
$im1 = imagerotate($im1,180,0);
break;
case
6:
$im1 = imagerotate($im1,-90,0);
break;
}
}
//}
$info = @getimagesize($pic);

$width = $info[0];

$w2=ImageSx($im1);
$h2=ImageSy($im1);
$w1 = ($thumbwidth <= $info[0]) ? $thumbwidth : $info[0] ;

$h1=floor($h2*($w1/$w2));
$im2=imagecreatetruecolor($w1,$h1);

imagecopyresampled ($im2,$im1,0,0,0,0,$w1,$h1,$w2,$h2);
$path=addslashes($thumb);
ImageJPEG($im2,$path,$quality);
ImageDestroy($im1);
ImageDestroy($im2);
}
?>
0
michael [at[ thisiswilson [dot[ com
15 年前
来自 - darkain at darkain dot com 的示例。

如果所有数据都来自同一张图片,只需

<?php
$exif_data
= exif_read_data ( $_FILES['photo']

$emake =$exif_data['Make'];
$emodel = $exif_data['Model'];
$eexposuretime = $exif_data['ExposureTime'];
$efnumber = $exif_data['FNumber'];
$eiso = $exif_data['ISOSpeedRatings'];
$edate = $exif_data['DateTime'];
?>

可以正常工作,我尝试使用 PEL 库,虽然很酷,但我无法理解如何调用某些东西,如果你的系统非常基础或者你很匆忙,这个方法更简单。如果你有时间,可以尝试玩 PEL。不过它目前没有维护..

http://pel.sourceforge.net/
0
匿名
17 年前
从 'WINXP' 组读取 EXIF 信息时,可能需要将使用的编码从默认的 "ISO-8859-15" 更改为 "UTF-8"。这可以在 php.ini 或代码中完成

<?php
ini_set
('exif.encode_unicode', 'UTF-8');

$exif = exif_read_data('TEST.JPG', 0, true);
echo
$exif['WINXP']['Title'];
?>

关于 EXIF 的有用文档
http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html
另请参见 XPTitle 和 XPAuthor 旁边的注释。
-1
iam at thatguy dot co dot za
10 年前
我发布了该函数的原始版本,但在使用了一段时间后,我发现我的错误检查做得不够。

我重新调整了代码结构,现在如果它无法读取图像的 exif,它将返回一个空数组。如果它能够读取,它将返回它能够检索到的详细信息。这应该不会出现错误。

我正在抑制错误,因为如果你传递无法解析的图像,你会得到一个警告。

<?php

# 修改后的 cameraUsed 版本,不再返回日期。
public function cameraUsed($imagePath)
{
# 默认的空返回
$return = array(
'make' => "",
'model' => "",
'exposure' => "",
'aperture' => "",
'iso' => ""
);

// 检查变量是否已设置,以及文件本身是否存在,然后继续
if ((isset($imagePath)) AND (file_exists($imagePath)))
{
// 有两个数组包含我们想要的信息,所以更容易声明它们
$exif_ifd0 = @read_exif_data($imagePath ,'IFD0' ,0);
$exif_exif = @read_exif_data($imagePath ,'EXIF' ,0);

# 确保我们确实获得了一些信息
if (($exif_ifd0 !== false) AND ($exif_exif !== false))
{
// 制造商
if (@array_key_exists('Make', $exif_ifd0))
{
$return['make'] = $exif_ifd0['Make'];
}

// 型号
if (@array_key_exists('Model', $exif_ifd0))
{
$return['model'] = $exif_ifd0['Model'];
}

// 曝光
if (@array_key_exists('ExposureTime', $exif_ifd0))
{
$return['exposure'] = $exif_ifd0['ExposureTime'];
}

// 光圈
if (@array_key_exists('ApertureFNumber', $exif_ifd0['COMPUTED']))
{
$return['aperture'] = $exif_ifd0['COMPUTED']['ApertureFNumber'];
}

// ISO
if (@array_key_exists('ISOSpeedRatings',$exif_exif))
{
$return['iso'] = $exif_exif['ISOSpeedRatings'];
}
}
}

# 返回空数组,或我们能够推断出的详细信息。
return $return;
}

?>
-1
wdierkes at 5dollarwhitebox dot org
16 年前
除非 exif 和 mbstring 都是静态编译的,否则使用 exif 方法读取 WINXP 数据会返回意外的结果。请参考以下错误报告

Bug #31980
Bug #23105


特别是 #23105 上的最后一条评论

"[2003 年 4 月 8 日 下午 4:26 UTC] [email protected]

由于 mbstring 已从 PHP 核心(已“解绑”)中删除,因此当它被编译为共享库(dll)时,核心文件和其他扩展无法使用 mbstring 功能。
"

如果 exif 以静态方式编译(--enable-exif)而 mbstring 以 DSO 模块编译(--enable-mbstring=shared),则 exif_read_data 可能会返回单个字符而不是整个字符串。

以静态方式编译 exif 和 mbstring(--enable-exif --enable-mbstring)可以解决该问题。
-3
lincolnzsilva at gmail dot com
15 年前
获取一些 EXIF 字段(简单方法)

<?php
$exif_make
= exif_read_data ( $_FILES['photo']['tmp_name'] ,'IFD0' ,0 );
$emake = $exif_make['Make'];

$exif_model = exif_read_data ( $_FILES['photo']['tmp_name'] ,'IFD0' ,0 );
$emodel = $exif_model['Model'];

$exif_exposuretime = exif_read_data ( $_FILES['photo']['tmp_name'] ,'EXIF' ,0 );
$eexposuretime = $exif_exposuretime['ExposureTime'];

$exif_fnumber = exif_read_data ( $_FILES['photo']['tmp_name'] ,'EXIF' ,0 );
$efnumber = $exif_fnumber['FNumber'];

$exif_iso = exif_read_data ( $_FILES['photo']['tmp_name'] ,'EXIF' ,0 );
$eiso = $exif_iso['ISOSpeedRatings'];

$exif_date = exif_read_data ( $_FILES['photo']['tmp_name'] ,'IFD0' ,0 );
$edate = $exif_date['DateTime'];
?>
-5
kurt at mandella dot biz
11 年前
在 Picasa 中处理的照片通常会在 "MAKERNOTE" 部分和 EXIF.MakerNote 下包含垃圾数据(UTF8),例如

[MakerNote] => r 0~ Þ æ "î 2 O Ôy e §… b ! ) ) EI " ÐÓ
# s & 0{ ' Û ( å - Ð ` ÿÿ @ÿ ÿÿìE è €Ýÿÿ ÿÿÿ ÿ ÿÿx "ú»Dóÿ H ? . }B úIMG:DIGITAL IXUS 100 IS JPEGFirmware Version 1.00 s › x Ç Øÿÿÿ– l ¥ÿÿÿ Ø Ì Ì x Œ ÿÿÌ Ì Ÿ ãÿÿÿ¼Ž(½ (½T‹ U ’ ‹ d – ~ Ø “ ¥ÿÿÿ Àÿ œ ª ã j á À pg a X f a W b [ T e «
8 ú5 : Áð- 3åÿÿ 5»ÿ ‹;ßÊ Š € à € ` ¸ dd îÿ îÿ îÿ îÿîÿîÿ
ÿÿ Š1—ÏàôÉæ× ¬gªiï

这些数据无法写入 MySql 的 Blob 中。以下代码将删除这些垃圾标签。

$exif = exif_read_data($process_photo, 0, 'EXIF');

if($exif['IFD0']['Software'] == "Picasa"){

foreach ($exif as $key => $section){

if($key != "MAKERNOTE"){
foreach ($section as $name => $val){
if($name != 'MakerNote'){
$exifA[$key][$name] = $val;
}
}
$exifB[$key] = $exifA[$key];
}
}
$serialized_exif = serialize ($exifB);
}else{
$serialized_exif = serialize ($exif);
}
To Top