Удалить данные EXIF из JPG с помощью PHP
Есть ли способ удалить данные EXIF из JPG с помощью PHP? Я слышал о ПЭЛЕ, но я надеюсь, что есть более простой способ. Я загружаю изображения, которые будут отображаться в Интернете, и хотел бы, чтобы данные EXIF были удалены.
Спасибо!
ИЗМЕНИТЬ: Я не могу/не могу установить ImageMagick.
8 answers
Используйте 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. взгляните на эту библиотеку, которая была бы полезна: http://www.sno.phy.queensu.ca /~фил/инструмент exiftool/
Приветствия,
Vfn
Я не совсем уверен в этом, но если это возможно с помощью GD
о 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);
}
Это прототип вызова из командной строки.