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 onli
this is the simplest way:
$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);
}
It is a prototype for a call from a command line.
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.
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.
$path = "/image.jpg";
$img = imagecreatefromjpeg ($path);
imagejpeg ($img, $path, 100);
imagedestroy ($img);
(simple approximation to the graph can be found here)
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/
Cheers,
vfn
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.
This option has several advantages...
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.
Here is my function...
/**
* 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);
}
The code is pretty simple. It opens the input file for reading and the output file for writing, and then starts reading the input file. It data from one to the other. Once it reaches the EXIF marker, it reads the length of the EXIF record and skips over that number of bytes. It then continues by reading and writing the remaining data.