Fix Exif TZ and handling for HEIC (fix #15)

pull/37/head
Varun Patil 2022-08-23 07:54:39 +00:00
parent eac3286846
commit 311d3ea279
1 changed files with 36 additions and 4 deletions

View File

@ -26,6 +26,16 @@ class Exif {
* @param File $file * @param File $file
*/ */
public static function getExifFromFile(File &$file) { public static function getExifFromFile(File &$file) {
// Borrowed from previews
// https://github.com/nextcloud/server/blob/19f68b3011a3c040899fb84975a28bd746bddb4b/lib/private/Preview/ProviderV2.php
if (!$file->isEncrypted() && $file->getStorage()->isLocal()) {
$path = $file->getStorage()->getLocalFile($file->getInternalPath());
if (is_string($path)) {
return self::getExifFromLocalPath($path);
}
}
// Fallback to reading as a stream
$handle = $file->fopen('rb'); $handle = $file->fopen('rb');
if (!$handle) { if (!$handle) {
throw new \Exception('Could not open file'); throw new \Exception('Could not open file');
@ -36,6 +46,28 @@ class Exif {
return $exif; return $exif;
} }
/** Get exif data as a JSON object from a local file path */
public static function getExifFromLocalPath(string $path) {
$pipes = [];
$proc = proc_open(['exiftool', '-json', $path], [
1 => array('pipe', 'w'),
2 => array('pipe', 'w'),
], $pipes);
$stdout = stream_get_contents($pipes[1]);
// Clean up
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($proc);
// Parse the json
$json = json_decode($stdout, true);
if (!$json) {
throw new \Exception('Could not read exif data');
}
return $json[0];
}
/** /**
* Get exif data as a JSON object from a stream. * Get exif data as a JSON object from a stream.
* @param resource $handle * @param resource $handle
@ -43,15 +75,15 @@ class Exif {
public static function getExifFromStream(&$handle) { public static function getExifFromStream(&$handle) {
// Start exiftool and output to json // Start exiftool and output to json
$pipes = []; $pipes = [];
$proc = proc_open('exiftool -json -', [ $proc = proc_open(['exiftool', '-json', '-fast', '-'], [
0 => array('pipe', 'rb'), 0 => array('pipe', 'rb'),
1 => array('pipe', 'w'), 1 => array('pipe', 'w'),
2 => array('pipe', 'w'), 2 => array('pipe', 'w'),
], $pipes); ], $pipes);
// Write the file to exiftool's stdin // Write the file to exiftool's stdin
// Assume exif exists in the first 256 kb of the file // Warning: this is slow for big files
stream_copy_to_stream($handle, $pipes[0], 256 * 1024); stream_copy_to_stream($handle, $pipes[0]);
fclose($pipes[0]); fclose($pipes[0]);
// Get output from exiftool // Get output from exiftool
@ -83,7 +115,7 @@ class Exif {
// Check if found something // Check if found something
if (isset($dt) && !empty($dt)) { if (isset($dt) && !empty($dt)) {
$dt = \DateTime::createFromFormat('Y:m:d H:i:s', $dt); $dt = \DateTime::createFromFormat('Y:m:d H:i:s', $dt, new \DateTimeZone("UTC"));
if ($dt && $dt->getTimestamp() > -5364662400) { // 1800 A.D. if ($dt && $dt->getTimestamp() > -5364662400) { // 1800 A.D.
return $dt->getTimestamp(); return $dt->getTimestamp();
} }