Удалить данные EXIF ​​из JPG с помощью PHP - PullRequest
16 голосов
/ 01 сентября 2010

Есть ли способ удалить данные EXIF ​​из JPG с помощью PHP?Я слышал о PEL, но я надеюсь, что есть более простой способ.Я загружаю изображения, которые будут отображаться в Интернете, и хотел бы удалить данные EXIF.

Спасибо!

РЕДАКТИРОВАТЬ: я не могу / не могу установить ImageMagick.

Ответы [ 8 ]

16 голосов
/ 01 сентября 2010

Быстрый способ сделать это в PHP с помощью ImageMagick (при условии, что он установлен и включен).

<?php

$images = glob('*.jpg');

foreach($images as $image) 
{   
    try
    {   
        $img = new Imagick($image);
        $img->stripImage();
        $img->writeImage($image);
        $img->clear();
        $img->destroy();

        echo "Removed EXIF data from $image. \n";

    } catch(Exception $e) {
        echo 'Exception caught: ',  $e->getMessage(), "\n";
    }   
}
?>
11 голосов
/ 01 сентября 2010

Используйте gd для воссоздания графической части изображения в новой, которую вы сохраняете с другим именем .

См. PHP GD


изменить 2017

Используйте новую функцию Imagick.

Открыть изображение:

<?php
    $incoming_file = '/Users/John/Desktop/file_loco.jpg';
    $img = new Imagick(realpath($incoming_file));

Обязательно сохраните любой профиль ICC на изображении

    $profiles = $img->getImageProfiles("icc", true);

затем снимите изображение и верните профиль обратно, если есть

    $img->stripImage();

    if(!empty($profiles)) {
       $img->profileImage("icc", $profiles['icc']);
    }

Приходит с этой страницы PHP , см. Комментарий Макса Еремина вниз по странице.

4 голосов
/ 10 августа 2016

Я тоже искал решение этой проблемы.В конце концов я использовал PHP для перезаписи JPEG с удалением ВСЕХ данных Exif.Мне это не понадобилось для моих целей.

У этой опции есть несколько преимуществ ...

  • Файл меньше, потому что данные EXIF ​​пропали.
  • Нет потери качества изображения (поскольку данные изображения не изменяются).

Также примечание об использовании imagecreatefromjpeg: я попробовал это, и мои файлы стали больше.Если вы установите качество 100, ваш файл будет БОЛЬШИМ, потому что изображение было пересчитано, а затем сохранено без потерь.И если вы не используете качество 100, вы теряете качество изображения.Единственный способ избежать повторной выборки - не использовать imagecreatefromjpeg.

Вот моя функция ...

function removeExif($old, $new)
{
    $f1 = fopen($old, 'rb');
    $f2 = fopen($new, 'wb');

    // Find EXIF marker
    while (($s = fread($f1, 2))) {
        $word = unpack('ni', $s)['i'];
        if ($word == 0xFFE1) {
            // Read length (includes the word used for the length)
            $s = fread($f1, 2);
            $len = unpack('ni', $s)['i'];
            // Skip the EXIF info
            fread($f1, $len - 2);
            break;
        } else {
            fwrite($f2, $s, 2);
        }
    }

    // Write the rest of the file
    while (($s = fread($f1, 4096))) {
        fwrite($f2, $s, strlen($s));
    }

    fclose($f1);
    fclose($f2);
}
4 голосов
/ 07 сентября 2012

Следующее удалит все данные EXIF ​​файла JPEG. Это сделает копию исходного файла без EXIF ​​и удалит старый файл. Используйте 100 качество, чтобы не потерять детали качества изображения.

$path = "/image.jpg";

$img = imagecreatefromjpeg ($path);
imagejpeg ($img, $path, 100);
imagedestroy ($img);

(простое приближение к графику можно найти здесь )

3 голосов
/ 07 ноября 2017
function remove_exif($in, $out)
{
    $buffer_len = 4096;
    $fd_in = fopen($in, 'rb');
    $fd_out = fopen($out, 'wb');
    while (($buffer = fread($fd_in, $buffer_len)))
    {
        //  \xFF\xE1\xHH\xLLExif\x00\x00 - Exif 
        //  \xFF\xE1\xHH\xLLhttp://      - XMP
        //  \xFF\xE2\xHH\xLLICC_PROFILE  - ICC
        //  \xFF\xED\xHH\xLLPhotoshop    - PH
        while (preg_match('/\xFF[\xE1\xE2\xED\xEE](.)(.)(exif|photoshop|http:|icc_profile|adobe)/si', $buffer, $match, PREG_OFFSET_CAPTURE))
        {
            echo "found: '{$match[3][0]}' marker\n";
            $len = ord($match[1][0]) * 256 + ord($match[2][0]);
            echo "length: {$len} bytes\n";
            echo "write: {$match[0][1]} bytes to output file\n";
            fwrite($fd_out, substr($buffer, 0, $match[0][1]));
            $filepos = $match[0][1] + 2 + $len - strlen($buffer);
            fseek($fd_in, $filepos, SEEK_CUR);
            echo "seek to: ".ftell($fd_in)."\n";
            $buffer = fread($fd_in, $buffer_len);
        }
        echo "write: ".strlen($buffer)." bytes to output file\n";
        fwrite($fd_out, $buffer, strlen($buffer));
    }
    fclose($fd_out);
    fclose($fd_in);
}

Это прототип для вызова из командной строки.

3 голосов
/ 11 мая 2014

это самый простой способ:

$images = glob($location.'/*.jpg');

foreach($images as $image) {   
    $img = imagecreatefromjpeg($image);
    imagejpeg($img,$image,100);
}
2 голосов
/ 01 сентября 2010

Я совершенно не понял вашего вопроса.

Вы можете использовать какой-либо инструмент командной строки, чтобы сделать эту работу. или напишите свое собственное расширение php, чтобы сделать это. взгляните на эту библиотеку, которая будет полезна: http://www.sno.phy.queensu.ca/~phil/exiftool/

Приветствия

VFN

1 голос
/ 01 сентября 2010

Я не совсем уверен в этом, но если это возможно, используя GD o ImageMagick, первое, что приходит мне в голову, это создать новый Изображение и добавьте старое изображение к новому.

...