Удаление данных GPS EXIF ​​с помощью PHP

Этим утром меня разбудил звонок от клиента, управляющего веб-сайтом Concrete5, и сказал, что все изображения, загруженные на их веб-сайт, внезапно перестали работать. После часа или двух экспериментов и изучения я понял основную причину проблемы. Пару дней назад этот клиент получил новый мобильный телефон (Samsung Epic), который записывает данные GPS EXIF ​​для каждого изображения. Она использовала этот мобильный телефон в качестве камеры, и по какой-то причине, если на изображении есть какие-либо данные GPS, Concrete5 взрывается. Я подозреваю, что это связано с тем, что данные GPS хранятся в виде массива, а не строки.

Я пытался работать над общей функцией для удаления любых данных EXIF, если существуют данные GPS EXIF. Вот что у меня есть (это находится в tools/files/importers):

$fileExtension = strtolower(substr($_FILES['Filedata']['name'], strrpos($_FILES['Filedata']['name'], '.')));
if ($fileExtension == ".jpg" || $fileExtension == ".jpeg"){
    /* File is a JPEG */
    if (exif_read_data($_FILES['Filedata']['tmp_name'], 'GPS') !== false){
        /* File contains GPS EXIF data */
        if (extension_loaded('magickwand') && function_exists("NewMagickWand")) {
            /* ImageMagick is installed and working */
            $img = new Imagick($_FILES['Filedata']['tmp_name']);
            $img->stripImage();
            $img->writeImage($_FILES['Filedata']['tmp_name']);
            $img->clear();
        } elseif (extension_loaded('gd') && function_exists('gd_info')) {
            /* GD is installed and working */
            $img = imagecreatefromjpeg($_FILES['Filedata']['tmp_name']);
            imagejpeg ($img, $_FILES['Filedata']['tmp_name']);
        } else {
            /* Neither ImageMagick nor GD are installed */
            die('No appropriate image handler to remove EXIF data');    
        }
    }
}

Даже с этим кодом, когда я загружаю изображение, данные EXIF ​​остаются. Я пробовал размещать die() команды по всему коду, чтобы точно определить, по какому пути идет код. На этом конкретном сервере я никогда не вхожу в блок if (extension_loaded('magickwand') && function_exists("NewMagickWand")), однако я вхожу в блок elseif (extension_loaded('gd') && function_exists('gd_info')). Поэтому мой код ImageMagick может быть в порядке, но кажется, что GD не удаляет данные EXIF ​​должным образом.

У кого-нибудь есть опыт работы с ImageMagick/GD или с данными PHP и EXIF?


person stevendesu    schedule 22.07.2011    source источник
comment
Если вы считаете, что проблема связана с конкретным5, вы должны отправить людям из converts5 несколько примеров изображений, которые ломают их программное обеспечение, и сообщить о проблеме, чтобы она была исправлена ​​в основном программном обеспечении.   -  person hakre    schedule 22.07.2011
comment
Я сделал. Я провел в IRC большую часть дня, но я хочу решить эту проблему сегодня, а не ждать обновления месяц.   -  person stevendesu    schedule 22.07.2011
comment
Да, сначала нужно исправить в любом случае.   -  person hakre    schedule 22.07.2011


Ответы (1)


Я провел тест на своем локальном компьютере, пытаясь удалить данные EXIF ​​по вашему методу, и это сработало ~ Он добавил эти данные комментария: CREATOR: gd-jpeg v1.0 (используя IJG JPEG v80), качество = 100

Какую версию gd-jpeg вы используете?

Кроме того, вы пробовали var_dump позвонить imagejpeg? Это может быть сбой ~ Мне никогда не удавалось писать в папку /tmp на любом сервере. Возможно, вам следует установить файл назначения где-нибудь под вашим веб-сайтом.

person Shad    schedule 22.07.2011
comment
Моя версия GD bundled (2.0.34 compatible). Я попытался заменить imagejpeg ($img, $_FILES['Filedata']['tmp_name']); на imagejpeg ($img, "test.jpg");, чтобы увидеть, какое изображение на самом деле создается (скрипт, который обрабатывает импорт, никогда не отображается - это загрузчик AJAX), но test.jpg так и не был создан. Я также попытался напечатать var_dump($img) в файл, и он был абсолютно пуст. Должен ли я попробовать var_dump(imagejpeg ($img))? - person stevendesu; 22.07.2011
comment
Быстрое дополнение к этому - я попробовал if($img === false){ fwrite($fp, 'img is false'); } (конечно, $fp был файловым указателем на файл, который я использовал для мониторинга вывода), и, конечно же, $img получает значение false. php.net/manual/en/function.imagecreatefromjpeg.php говорит, что false возвращается при ошибках, но не указывает, какой тип ошибок может вызвать это. Любые идеи? - person stevendesu; 22.07.2011
comment
@steven Похоже, у меня есть права на запись. Я бы порекомендовал скопировать файл из его tmp_name в то место, где, как вы знаете, у вас есть разрешение на запись, а затем запустить ваши процессы в только что созданном файле (отлаживая каждый шаг на этом пути); Я бы продолжал проверять, что $img является действительным ресурсом, и дополнительно зафиксировал возврат от вызова к imagejpeg (, так как он также может быть ложным =) - person Shad; 22.07.2011
comment
Я скопировал $_FILES['Filedata']['tmp_name'] в test.jpg (в папку, где у меня были разрешения rwx), и файл скопировался нормально, но imagecreatefromjpeg() по-прежнему возвращал false. Я уверен, что пока $img ложно, imagejpeg() также вернет false. Любые другие идеи? Кажется, что GD просто сломан, но Concrete5 использует GD для создания эскизов. Может ли моя версия GD не анализировать изображения с данными GPS EXIF ​​(объясняя, почему C5 не работает)? - person stevendesu; 22.07.2011
comment
@ Стивен, Боже ... ну, ты включил отчеты об ошибках? ini_set('display_errors',1) (И если бы вы все еще делали это через AJAX, я бы рекомендовал переключиться на файл с прямым доступом, чтобы вы могли видеть все выходные данные.) Ваша теория кажется мне наиболее правдоподобной. - person Shad; 22.07.2011
comment
Переключиться на сайт с прямым доступом будет немного сложно, так как я работаю с Concrete5, и для этого потребуется либо изменить правила .htaccess для перенаправления на мой временный тестовый сценарий, либо изменить весь файловый менеджер. Хотя я могу использовать ob_start(), ob_get_contents() и ob_end_clean() для просмотра вывода. Я опубликую любые результаты, как только сделаю это - у меня есть несколько других задач, которые сегодня имеют приоритет. - person stevendesu; 23.07.2011