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

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

спасибо!

EDIT: я не/не могу установить ImageMagick.

8 ответов


использовать 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, см. комментарий от Макса Еремина вниз по странице.


быстрый способ сделать это в 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";
    }   
}
?>

Я тоже искал решение для этого. В конце концов я использовал 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);
}

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

$path = "/image.jpg";

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

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


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

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

спасибо,

vfn


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


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

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

foreach($images as $image) {   
    $img = imagecreatefromjpeg($image);
    imagejpeg($img,$image,100);
}

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);
}

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