PHP 大会日本 2024

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 头信息。这样你就可以读取数码相机生成的元数据。

EXIF 头信息通常存在于数码相机生成的 JPEG/TIFF 图像中,但不幸的是,每个数码相机制造商对如何实际标记图像都有不同的想法,因此你不能总是依赖于特定的 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 规范验证 EXIF 数据标签(» http://exif.org/Exif2-2.PDF,第 20 页)。

参数

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 现在可以为 null。
7.2.0 file 参数现在同时支持本地文件和流资源。
7.2.0

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

  • 三星
  • 大疆
  • 松下
  • 索尼
  • 宾得
  • 美能达
  • 适马/福唯
  • 爱克发
  • 京瓷
  • 理光
  • 爱普生

示例

示例 #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 条注释

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 上传的任何图像的方向。照片的方向是知道如何正确旋转它的关键。
Tim
5 年前
以下代码
<?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"
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);
}
?>
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,这些字段将显示“不可用”。

希望您觉得这有帮助。
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 (感谢)
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";
}
}

}
?>
TNTcode
7 年前
<?php

// 根据相机 EXIF 数据自动旋转图像文件
// 如果指定了目标文件,则将其保存到该文件,否则将其显示给用户
// 请注意,当 EXIF 数据方向为 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);

}
}
}
}

?>
Eion Robb
9 年前
我需要使用 exif_read_data() 读取方向标志,却发现 web 主机没有提供可用的 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]);
}
?>
dbareis at gmail dot com
5 个月前
Windows 字段位于“WINXP”部分(格式未知),但它们也位于其他地方,包括以 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;
}
service at tianex dot com
11 个月前
获取 jpeg 文件 EXIF 信息时发生此错误

exif_read_data(): Error reading from file: got=x3FFA(=16378) != itemlen-2=x4325(=17189)
b at asdflolinternet dot de
9 年前
例如,当值(例如 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));
//
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

我发现 ShutterSppedValue 的显示选项也可以是 exif 数据中的 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) . '秒';
};
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);

//如果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);
}
?>
michael [at[ thisiswilson [dot[ com
16 年前
来自 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/
匿名
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 旁边的注释。
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;
}

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

错误 #31980
错误 #23105


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

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

由于 mbstring 已从 PHP 核心移除(已“取消捆绑”),并且核心文件和其他扩展在将 mbstring 编译为共享库(dll)时无法使用 mbstring 功能,因此无法修复此问题。
"

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

静态编译 exif 和 mbstring(--enable-exif --enable-mbstring)可以解决此问题。
lincolnzsilva at gmail dot com
16 年前
获取一些 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'];
?>
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