123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- <?php
- /**
- * PHP Exif Exiftool Reader Adapter
- *
- * @link http://github.com/miljar/PHPExif for the canonical source repository
- * @copyright Copyright (c) 2013 Tom Van Herreweghe <tom@theanalogguy.be>
- * @license http://github.com/miljar/PHPExif/blob/master/LICENSE MIT License
- * @category PHPExif
- * @package Reader
- */
- namespace PHPExif\Adapter;
- use PHPExif\Exif;
- use InvalidArgumentException;
- use RuntimeException;
- /**
- * PHP Exif Exiftool Reader Adapter
- *
- * Uses native PHP functionality to read data from a file
- *
- * @category PHPExif
- * @package Reader
- */
- class Exiftool extends AdapterAbstract
- {
- const TOOL_NAME = 'exiftool';
- /**
- * Path to the exiftool binary
- *
- * @var string
- */
- protected $toolPath;
- /**
- * @var boolean
- */
- protected $numeric = true;
- /**
- * @var array
- */
- protected $encoding = array();
- /**
- * @var string
- */
- protected $mapperClass = '\\PHPExif\\Mapper\\Exiftool';
- /**
- * Setter for the exiftool binary path
- *
- * @param string $path The path to the exiftool binary
- * @return \PHPExif\Adapter\Exiftool Current instance
- * @throws \InvalidArgumentException When path is invalid
- */
- public function setToolPath($path)
- {
- if (!file_exists($path)) {
- throw new InvalidArgumentException(
- sprintf(
- 'Given path (%1$s) to the exiftool binary is invalid',
- $path
- )
- );
- }
- $this->toolPath = $path;
- return $this;
- }
- /**
- * @param boolean $numeric
- */
- public function setNumeric($numeric)
- {
- $this->numeric = $numeric;
- }
- /**
- * @see http://www.sno.phy.queensu.ca/~phil/exiftool/faq.html#Q10
- * @param array $encoding encoding parameters in an array eg. ["exif" => "UTF-8"]
- */
- public function setEncoding($encoding)
- {
- $possible_keys = array("exif", "iptc", "id3", "photoshop", "quicktime",);
- $possible_values = array("UTF8", "cp65001", "UTF-8", "Thai", "cp874", "Latin", "cp1252",
- "Latin1", "MacRoman", "cp10000", "Mac", "Roman", "Latin2", "cp1250", "MacLatin2",
- "cp10029", "Cyrillic", "cp1251", "Russian", "MacCyrillic", "cp10007", "Greek",
- "cp1253", "MacGreek", "cp10006", "Turkish", "cp1254", "MacTurkish", "cp10081",
- "Hebrew", "cp1255", "MacRomanian", "cp10010", "Arabic", "cp1256", "MacIceland",
- "cp10079", "Baltic", "cp1257", "MacCroatian", "cp10082", "Vietnam", "cp1258",);
- foreach ($encoding as $type => $encoding) {
- if (in_array($type, $possible_keys) && in_array($encoding, $possible_values)) {
- $this->encoding[$type] = $encoding;
- }
- }
- }
- /**
- * Getter for the exiftool binary path
- * Lazy loads the "default" path
- *
- * @return string
- */
- public function getToolPath()
- {
- if (empty($this->toolPath)) {
- $path = exec('which ' . self::TOOL_NAME);
- $this->setToolPath($path);
- }
- return $this->toolPath;
- }
- /**
- * Reads & parses the EXIF data from given file
- *
- * @param string $file
- * @return \PHPExif\Exif Instance of Exif object with data
- * @throws \RuntimeException If the EXIF data could not be read
- */
- public function getExifFromFile($file)
- {
- $encoding = '';
- if (!empty($this->encoding)) {
- $encoding = '-charset ';
- foreach ($this->encoding as $key => $value) {
- $encoding .= escapeshellarg($key).'='.escapeshellarg($value);
- }
- }
- $result = $this->getCliOutput(
- sprintf(
- '%1$s%3$s -j -a -G1 %5$s -c %4$s %2$s',
- $this->getToolPath(),
- escapeshellarg($file),
- $this->numeric ? ' -n' : '',
- escapeshellarg('%d deg %d\' %.4f"'),
- $encoding
- )
- );
- if (!mb_check_encoding($result, "utf-8")) {
- $result = utf8_encode($result);
- }
- $data = json_decode($result, true);
- if (!is_array($data)) {
- throw new RuntimeException(
- 'Could not decode exiftool output'
- );
- }
- // map the data:
- $mapper = $this->getMapper();
- $mapper->setNumeric($this->numeric);
- $mappedData = $mapper->mapRawData(reset($data));
- // hydrate a new Exif object
- $exif = new Exif();
- $hydrator = $this->getHydrator();
- $hydrator->hydrate($exif, $mappedData);
- $exif->setRawData(reset($data));
- return $exif;
- }
- /**
- * Returns the output from given cli command
- *
- * @param string $command
- * @return mixed
- * @throws RuntimeException If the command can't be executed
- */
- protected function getCliOutput($command)
- {
- $descriptorspec = array(
- 0 => array('pipe', 'r'),
- 1 => array('pipe', 'w'),
- 2 => array('pipe', 'a')
- );
- $process = proc_open($command, $descriptorspec, $pipes);
- if (!is_resource($process)) {
- throw new RuntimeException(
- 'Could not open a resource to the exiftool binary'
- );
- }
- $result = stream_get_contents($pipes[1]);
- fclose($pipes[0]);
- fclose($pipes[1]);
- fclose($pipes[2]);
- proc_close($process);
- return $result;
- }
- }
|