使用PHP从JPG中删除EXIF数据

时间:2022-01-18 08:56:46

Is there any way to remove the EXIF data from a JPG using PHP? I have heard of PEL, but I'm hoping there's a simpler way. I am uploading images that will be displayed online and would like the EXIF data removed.

有没有办法使用PHP从JPG中删除EXIF数据?我听说过PEL,但我希望有一种更简单的方法。我正在上传将在线显示的图片,并希望删除EXIF数据。

Thanks!

EDIT: I don't/can't install ImageMagick.

编辑:我不能/不能安装ImageMagick。

8 个解决方案

#1


8  

Use gd to recreate the graphical part of the image in a new one, that you save with another name.

使用gd以新的名称重新创建图像的图形部分,并使用其他名称保存。

See PHP gd

请参阅PHP gd


edit 2017

Use the new Imagick feature.

使用新的Imagick功能。

Open Image:

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

Be sure to keep any ICC profile in the image

请务必在图像中保留任何ICC配置文件

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

then strip image, and put the profile back if any

然后剥离图像,然后将配置文件放回去

    $img->stripImage();

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

Comes from this PHP page, see comment from Max Eremin down the page.

来自这个PHP页面,请参阅Max Eremin的评论。

#2


15  

A fast way to do it in PHP using ImageMagick (Assuming you have it installed and enabled).

使用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";
    }   
}
?>

#3


4  

I was looking for a solution to this as well. In the end I used PHP to rewrite the JPEG with ALL Exif data removed. I didn't need any of it for my purposes.

我也在寻找解决方案。最后,我使用PHP重写了JPEG,删除了所有Exif数据。我不需要任何这个用于我的目的。

This option has several advantages...

这个选项有几个优点......

  • The file is smaller because the EXIF data is gone.
  • 该文件较小,因为EXIF数据消失了。

  • There is no loss of image quality (because the image data is unchanged).
  • 不会损失图像质量(因为图像数据不变)。

Also a note on using imagecreatefromjpeg: I tried this and my files got bigger. If you set quality to 100, your file will be LARGER, because the image has been resampled, and then stored in a lossless way. And if you don't use quality 100, you lose image quality. The ONLY way to avoid resampling is to not use imagecreatefromjpeg.

还有关于使用imagecreatefromjpeg的说明:我试过这个,我的文件变大了。如果将质量设置为100,则文件将更大,因为图像已经过重新采样,然后以无损方式存储。如果您不使用质量100,则会丢失图像质量。避免重新采样的唯一方法是不使用imagecreatefromjpeg。

Here is my function...

这是我的功能......

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


2  

The following will remove all EXIF data of a jpeg file. This will make a copy of original file without EXIF and remove the old file. Use 100 quality not to loose any quality details of picture.

以下将删除jpeg文件的所有EXIF数据。这将生成没有EXIF的原始文件的副本并删除旧文件。使用100质量不会丢失图片的任何质量细节。

$path = "/image.jpg";

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

(simple approximation to the graph can be found here)

(图表的简单近似可以在这里找到)

#5


1  

I completely misunderstood your question.

我完全误解了你的问题。

You could use some command line tool to do this job. or write your own php extension to do it. have a look at this lib that would be useful: http://www.sno.phy.queensu.ca/~phil/exiftool/

您可以使用一些命令行工具来完成这项工作。或者编写自己的php扩展来完成它。看看这个有用的库:http://www.sno.phy.queensu.ca/~phil/exiftool/

Cheers,

vfn

#6


1  

I'm not pretty sure about it, but if its possible using GD o ImageMagick, the first thing that come to my mind is to create a new Image and add the old image to the new one.

我不太确定它,但如果它可能使用GD o ImageMagick,我想到的第一件事是创建一个新的图像并将旧图像添加到新图像。

#7


1  

this is the simplest way:

这是最简单的方法:

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

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

#8


1  

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

It is a prototype for a call from a command line.

它是来自命令行的调用的原型。

#1


8  

Use gd to recreate the graphical part of the image in a new one, that you save with another name.

使用gd以新的名称重新创建图像的图形部分,并使用其他名称保存。

See PHP gd

请参阅PHP gd


edit 2017

Use the new Imagick feature.

使用新的Imagick功能。

Open Image:

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

Be sure to keep any ICC profile in the image

请务必在图像中保留任何ICC配置文件

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

then strip image, and put the profile back if any

然后剥离图像,然后将配置文件放回去

    $img->stripImage();

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

Comes from this PHP page, see comment from Max Eremin down the page.

来自这个PHP页面,请参阅Max Eremin的评论。

#2


15  

A fast way to do it in PHP using ImageMagick (Assuming you have it installed and enabled).

使用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";
    }   
}
?>

#3


4  

I was looking for a solution to this as well. In the end I used PHP to rewrite the JPEG with ALL Exif data removed. I didn't need any of it for my purposes.

我也在寻找解决方案。最后,我使用PHP重写了JPEG,删除了所有Exif数据。我不需要任何这个用于我的目的。

This option has several advantages...

这个选项有几个优点......

  • The file is smaller because the EXIF data is gone.
  • 该文件较小,因为EXIF数据消失了。

  • There is no loss of image quality (because the image data is unchanged).
  • 不会损失图像质量(因为图像数据不变)。

Also a note on using imagecreatefromjpeg: I tried this and my files got bigger. If you set quality to 100, your file will be LARGER, because the image has been resampled, and then stored in a lossless way. And if you don't use quality 100, you lose image quality. The ONLY way to avoid resampling is to not use imagecreatefromjpeg.

还有关于使用imagecreatefromjpeg的说明:我试过这个,我的文件变大了。如果将质量设置为100,则文件将更大,因为图像已经过重新采样,然后以无损方式存储。如果您不使用质量100,则会丢失图像质量。避免重新采样的唯一方法是不使用imagecreatefromjpeg。

Here is my function...

这是我的功能......

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


2  

The following will remove all EXIF data of a jpeg file. This will make a copy of original file without EXIF and remove the old file. Use 100 quality not to loose any quality details of picture.

以下将删除jpeg文件的所有EXIF数据。这将生成没有EXIF的原始文件的副本并删除旧文件。使用100质量不会丢失图片的任何质量细节。

$path = "/image.jpg";

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

(simple approximation to the graph can be found here)

(图表的简单近似可以在这里找到)

#5


1  

I completely misunderstood your question.

我完全误解了你的问题。

You could use some command line tool to do this job. or write your own php extension to do it. have a look at this lib that would be useful: http://www.sno.phy.queensu.ca/~phil/exiftool/

您可以使用一些命令行工具来完成这项工作。或者编写自己的php扩展来完成它。看看这个有用的库:http://www.sno.phy.queensu.ca/~phil/exiftool/

Cheers,

vfn

#6


1  

I'm not pretty sure about it, but if its possible using GD o ImageMagick, the first thing that come to my mind is to create a new Image and add the old image to the new one.

我不太确定它,但如果它可能使用GD o ImageMagick,我想到的第一件事是创建一个新的图像并将旧图像添加到新图像。

#7


1  

this is the simplest way:

这是最简单的方法:

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

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

#8


1  

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

It is a prototype for a call from a command line.

它是来自命令行的调用的原型。