pics/models/EXIF.php

136 lines
3.8 KiB
PHP

<?php
class EXIF
{
public $aperture = 0;
public $credit = '';
public $camera = '';
public $caption = '';
public $created_timestamp = 0;
public $copyright = '';
public $focal_length = 0;
public $iso = 0;
public $shutter_speed = 0;
public $title = '';
private function __construct(array $meta)
{
foreach ($meta as $key => $value)
$this->$key = $value;
}
public static function fromFile($file, $as_array = false, $override_cache = false)
{
if (!file_exists($file))
return false;
$meta = [
'aperture' => 0,
'credit' => '',
'camera' => '',
'caption' => '',
'created_timestamp' => 0,
'copyright' => '',
'focal_length' => 0,
'iso' => 0,
'shutter_speed' => 0,
'title' => '',
];
if (!function_exists('exif_read_data'))
throw new Exception("The PHP module 'exif' appears to be disabled. Please enable it to use EXIF functions.");
list(, , $image_type) = getimagesize($file);
if (!in_array($image_type, [IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM]))
return new self($meta);
$exif = @exif_read_data($file);
if (!empty($exif['Title']))
$meta['title'] = trim($exif['Title']);
if (!empty($exif['ImageDescription']))
{
if (empty($meta['title']) && strlen($exif['ImageDescription']) < 80)
{
$meta['title'] = trim($exif['ImageDescription']);
if (!empty($exif['COMPUTED']['UserComment']) && trim($exif['COMPUTED']['UserComment']) != $meta['title'])
$meta['caption'] = trim($exif['COMPUTED']['UserComment']);
}
elseif (trim($exif['ImageDescription']) != $meta['title'])
$meta['caption'] = trim($exif['ImageDescription']);
}
elseif (!empty($exif['Comments']) && trim($exif['Comments']) != $meta['title'])
$meta['caption'] = trim($exif['Comments']);
if (!empty($exif['Artist']))
$meta['credit'] = trim($exif['Artist']);
elseif (!empty($exif['Author']))
$meta['credit'] = trim($exif['Author']);
if (!empty($exif['Copyright']))
$meta['copyright'] = trim($exif['Copyright']);
if (!empty($exif['ExposureTime']))
$meta['shutter_speed'] = (string) self::frac2dec($exif['ExposureTime']);
if (!empty($exif['FNumber']))
$meta['aperture'] = round(self::frac2dec($exif['FNumber']), 2);
if (!empty($exif['FocalLength']))
$meta['focal_length'] = (string) self::frac2dec($exif['FocalLength']);
if (!empty($exif['ISOSpeedRatings']))
{
$meta['iso'] = is_array($exif['ISOSpeedRatings']) ? reset($exif['ISOSpeedRatings']) : $exif['ISOSpeedRatings'];
$meta['iso'] = trim($meta['iso']);
}
if (!empty($exif['Model']))
{
if (!empty($exif['Make']) && strpos($exif['Model'], $exif['Make']) === false)
$meta['camera'] = trim($exif['Make']) . ' ' . trim($exif['Model']);
else
$meta['camera'] = trim($exif['Model']);
}
elseif (!empty($exif['Make']))
$meta['camera'] = trim($exif['Make']);
if (!empty($exif['DateTimeDigitized']))
$meta['created_timestamp'] = self::toUnixTime($exif['DateTimeDigitized']);
return new self($meta);
}
public function shutterSpeedFraction()
{
$speed = $this->shutter_speed;
if (empty($this->shutter_speed))
return '';
if (1 / $this->shutter_speed <= 1)
return $this->shutter_speed . ' seconds';
$speed = (float) 1 / $this->shutter_speed;
if (in_array($speed, [1.3, 1.5, 1.6, 2.5]))
return "1/" . number_format($speed, 1, '.', '') . ' second';
else
return "1/" . number_format($speed, 0, '.', '') . ' second';
}
// Convert a fraction string to a decimal.
private static function frac2dec($str)
{
@list($n, $d) = explode('/', $str);
return !empty($d) ? $n / $d : $str;
}
// Convert an EXIF formatted date to a UNIX timestamp.
private static function toUnixTime($str)
{
@list($date, $time) = explode(' ', trim($str));
@list($y, $m, $d) = explode(':', $date);
return strtotime("{$y}-{$m}-{$d} {$time}");
}
}