diff --git a/lib/PHPExif/Adapter/Exiftool.php b/lib/PHPExif/Adapter/Exiftool.php index 2319dee..d9e0c68 100644 --- a/lib/PHPExif/Adapter/Exiftool.php +++ b/lib/PHPExif/Adapter/Exiftool.php @@ -39,6 +39,11 @@ class Exiftool extends AdapterAbstract */ protected $numeric = true; + /** + * @var array + */ + protected $encoding = array(); + /** * @var string */ @@ -75,6 +80,26 @@ 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 @@ -100,17 +125,33 @@ public function getToolPath() */ 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 -c %4$s %2$s', + '%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"') + escapeshellarg('%d deg %d\' %.4f"'), + $encoding ) ); - $data = json_decode(utf8_encode($result), true); + 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(); diff --git a/tests/PHPExif/Adapter/ExiftoolTest.php b/tests/PHPExif/Adapter/ExiftoolTest.php index 71abd2a..49029e5 100644 --- a/tests/PHPExif/Adapter/ExiftoolTest.php +++ b/tests/PHPExif/Adapter/ExiftoolTest.php @@ -78,6 +78,23 @@ public function testSetNumericInProperty() $this->assertEquals($expected, $reflProperty->getValue($this->adapter)); } + /** + * @see URI http://www.sno.phy.queensu.ca/~phil/exiftool/faq.html#Q10 + * @group exiftool + * @covers \PHPExif\Adapter\Exiftool::setEncoding + */ + public function testSetEncodingInProperty() + { + $reflProperty = new \ReflectionProperty('\PHPExif\Adapter\Exiftool', 'encoding'); + $reflProperty->setAccessible(true); + + $expected = array('iptc' => 'cp1250'); + $input = array('iptc' => 'cp1250', 'exif' => 'utf8', 'foo' => 'bar'); + $this->adapter->setEncoding($input); + + $this->assertEquals($expected, $reflProperty->getValue($this->adapter)); + } + /** * @group exiftool * @covers \PHPExif\Adapter\Exiftool::getExifFromFile @@ -85,6 +102,21 @@ public function testSetNumericInProperty() public function testGetExifFromFile() { $file = PHPEXIF_TEST_ROOT . '/files/morning_glory_pool_500.jpg'; + $this->adapter->setOptions(array('encoding' => array('iptc' => 'cp1252'))); + $result = $this->adapter->getExifFromFile($file); + $this->assertInstanceOf('\PHPExif\Exif', $result); + $this->assertInternalType('array', $result->getRawData()); + $this->assertNotEmpty($result->getRawData()); + } + + /** + * @group exiftool + * @covers \PHPExif\Adapter\Exiftool::getExifFromFile + */ + public function testGetExifFromFileWithUtf8() + { + $file = PHPEXIF_TEST_ROOT . '/files/utf8.jpg'; + $this->adapter->setOptions(array('encoding' => array('iptc' => 'utf8'))); $result = $this->adapter->getExifFromFile($file); $this->assertInstanceOf('\PHPExif\Exif', $result); $this->assertInternalType('array', $result->getRawData()); diff --git a/tests/files/utf8.jpg b/tests/files/utf8.jpg new file mode 100644 index 0000000..2b70059 Binary files /dev/null and b/tests/files/utf8.jpg differ