Подтвердить что ты не робот

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

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

Спасибо!

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

4b9b3361

Ответ 1

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

Ответ 2

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

Ответ 3

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

Эта опция имеет несколько преимуществ...

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

Также обратите внимание на использование imagecreatefromjpeg: я попробовал это, и мои файлы стали больше. Если вы установите качество 100, ваш файл будет LARGER, потому что изображение было повторно сэмплировано, а затем сохранено без потерь. И если вы не используете качество 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

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

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

Приветствия,

VFN

Ответ 5

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

Ответ 6

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

$path = "/image.jpg";

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

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

Ответ 7

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

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

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

Ответ 8

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

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