有没有办法使用PHP从JPG中删除EXIF数据?我听说过PEL,但希望有更简单的方法。我正在上传将在线显示的图像,并希望删除EXIF数据。
谢谢!
编辑:我不想/不能安装ImageMagick。
有没有办法使用PHP从JPG中删除EXIF数据?我听说过PEL,但希望有更简单的方法。我正在上传将在线显示的图像,并希望删除EXIF数据。
谢谢!
编辑:我不想/不能安装ImageMagick。
使用gd
在一个新图像中重新创建图像的图形部分,并将其以另一个名称保存。
请参见PHP gd
使用新的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的评论。
使用ImageMagick在PHP中快速完成此操作(假设您已安装并启用它)。
<?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";
}
}
?>
$profilesArray = $image->getImageProfiles("*",false);
以获取存在的配置文件数组,然后循环遍历该数组并运行 $image->removeImageProfile('profilename');
,除非 profilename 是 'icc'。虽然我没有测试过。 - jamesinealing我也在寻找解决方法。最终,我使用PHP重写了JPEG图像,并删除了所有的Exif数据。对于我的目的,我不需要这些数据。
这个选项有几个优点...
另外,关于使用imagecreatefromjpeg的注意事项:我尝试过这个函数,但我的文件变大了。如果您将质量设置为100,您的文件会变大,因为图像已经被重新采样,然后以无损方式存储。如果您不使用质量100,那么就会失去图像质量。避免重新采样的唯一方法是不使用imagecreatefromjpeg。
这是我的函数...
/**
* Remove EXIF from a JPEG file.
* @param string $old Path to original jpeg file (input).
* @param string $new Path to new jpeg file (output).
*/
function removeExif($old, $new)
{
// Open the input file for binary reading
$f1 = fopen($old, 'rb');
// Open the output file for binary writing
$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标记,它会读取EXIF记录的长度并跳过相应数量的字节。然后它继续读取和写入剩余的数据。
copy($new, $old);
和 unlink($new);
以保留原始文件名,这是非常有用的代码段 =) - PsychoMantisfunction 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);
}
这是一个命令行调用原型。
imagecreatefromjpeg
。 - kodfire$path = "/image.jpg";
$img = imagecreatefromjpeg ($path);
imagejpeg ($img, $path, 100);
imagedestroy ($img);
这里提供一个简单的图形近似,可以在这里找到。
ImageMagick
。 - Eje$images = glob($location.'/*.jpg');
foreach($images as $image) {
$img = imagecreatefromjpeg($image);
imagejpeg($img,$image,100);
}
我完全误解了你的问题。
你可以使用一些命令行工具来完成这项工作,或者编写自己的php扩展来完成。看一下这个相当有用的库:http://www.sno.phy.queensu.ca/~phil/exiftool/
祝好运,
vfn
$res = imagecreatefromjpeg($filename)
加载图像,然后imagejpeg ($res, $filename, QUALITY)
,将 Quality 设置为 100 - 如果有任何损失,应该是最小的。 - Déjà vu