How to strip exif data from jpg image using Imagine/Imagick? - php

I'd like to optimize jpg image size by deleting exif metadata from it. I use Imagick and Imagine libraries to achieve this goal:
$image = $this->imagine->open($currentImagePath);
$iccProfile = $image->palette()->profile();
$image->strip();
$image->profile($iccProfile);
$image->save($optimizedImagePath);
But it doesn't work properly, it actually deletes all metadata from image including icc. Is there a way to delete just exif from jpg image using Imagine and Imagick?

Related

Increment file size after convert image with PHP imagick

I have a function to convert jpg image to tiff image, keep the original size and quality. I used Imagick class to do that. Convert success but image size has increment too much. My original image was taken from iPhone with 2.6Mb after converting, it increment to 36.6Mb.
I had tried to use some PHP image manipulation libraries like Intervention/image but nothing change.
I also test convert original jpg to new jpg and file size increment from 2.6Mb to 3.3Mb.
My code here:
$image = new \Imagick('image_path_file.jpg);
$image->setImageFormat("tiff");
$image->writeImage("path_new_file.tiff");
Have any options that can help Imagick not increment file size too much?
Thanks you 🙇‍♂️

PHP Imagick ReadImage WriteImage different quality

I am scaling images with php-imagick. The image I want to scale is a jpg without exif data (1600x1200+0+0 8-bit sRGB). The quality of the scaled image is lower than the original. By quality I mean that the image has more artifacts (visible quality). So I made a test where I simply read an image and write it under another filename without chaning anything else:
$im = new Imagick();
$im->readImage(realpath('./a.jpg')); // image quality checked with $im->getImageCompressionQuality() 50
$im->writeImage('./b.jpg'); // image quality checked with $im->getImageCompressionQuality() 50
The result is:
Image a.jpg > 254kb (original image)
Image b.jpg > 183kb
So by simply writing the image to a new file, php-imagick changes something that I don't want.
Can anyone explain to me:
What happens to the generated image?
How can I write the image without changing any other stuff except scaling?
Thanks

Image upload security - reprocess with GD

I've heard that the best way to handle uploaded images is to "re-process" them using the GD library and save the processed image. see: PHP image upload security check list
My question is how do this "re-processing" in GD? What this means exactly? I don't know the GD library very well and I'm afraid I will mess it up...
So if anyone who did this before could you give me an example for this?
(I know, another other option is to use ImageMagick. For ImageMagick I found an answer here: Remove EXIF data from JPG using PHP, but I can't use ImgMagick now. By the way.. removing EXIF data means completely recreate the image in this case?)
(I'm using Zend Framework if someone interested.)
If the user uploads a JPEG file, you could do something like this to reprocess it:
$newIm = #imagecreatefromjpeg($_FILES['file']['tmp_name']);
if (!$newIm) {
// gd could not create an image from the source
// most likely, the file was not a valid jpeg image
}
You could then discard the $newIm image using imagedestroy() and use the uploaded file from the user, or save out the image from GD and use that. There could be some issues with saving the GD image as it is not the original image.
Another simple method would be to check the header (first several bytes) of the image file to make sure it is correct; for example all JPEG files begin with 0xff 0xd8.
See also imagecreatefromstring(), and you can also use getimagesize() to run similar checks on the uploaded image.
function isvalidjpeg($file)
{
$finfo = finfo_open(FILEINFO_MIME_TYPE);
return is_resource($finfo) &&
(finfo_file($finfo, $file) === 'image/jpeg') &&
finfo_close($finfo);
}
if(isvalidjpeg($_FILES['file']['tmp_name'])) {
$newIm = #imagecreatefromjpeg($_FILES['file']['tmp_name']); .....

imagemagick - downsize/crop/save to jpeg in one go?

I have a php script that will receive a bunch of images uploaded.
What I need to do is create a small thumbnail of each, on the fly using imagemagick.
I can do that easy enough but I also need to crop it so that the thumbnail is always 100x100.
the images supplied won't be the same proportions so simply downsizing won't work.
Can I downsize, crop to 100x100 and save to jpeg all in one step?
I believe this should do what you want:
convert 'just_uploaded/*' -resize 100x100^ -gravity center -extent 100x100 -set filename:f '%t' +adjoin 'just_uploaded_thumbs/%[filename:f].jpg'
resize will downsize, extent (in combination with gravity) will crop, and the rest takes care of saving with a modified name, in JPEG format, in a different directory.
Short answer: no. That'll be 3 steps, no less.
Longer answer: you can do it using the command line interface. In PHP, the only way is to write a function that will do what you ask. Then, for each image, you can just call your function. I'm not sure how this is more beneficial than just using the 3 Imagick functions separately...
I like the sfThumbnailPlugin. It wraps around both ImageMagick or GD
http://www.symfony-project.org/plugins/sfThumbnailPlugin
Example:
public function executeUpload()
{
// Retrieve the name of the uploaded file
$fileName = $this->getRequest()->getFileName('file');
// Create the thumbnail
$thumbnail = new sfThumbnail(150, 150);
$thumbnail->loadFile($this->getRequest()->getFilePath('file'));
$thumbnail->save(sfConfig::get('sf_upload_dir').'/thumbnail/'.$fileName, 'image/png');
// Move the uploaded file to the 'uploads' directory
$this->getRequest()->moveFile('file', sfConfig::get('sf_upload_dir').'/'.$fileName);
// Do whatever is next
$this->redirect('media/show?filename='.$fileName);
}

Get image size from handler

I'm creating an image editor in JS/PHP, but now I'm having trouble. First of all, I load the image from the database (load a blob with imagecreatefromstring). Then I apply a list of actions to this image. But how can I get the image size from this image handler I have then? Without writing it to a file or use a stream object. How??
In case you mean the image dimensions:
$width = imagesx($imgHandle);
$height = imagesy($imgHandle);
See imagesx() and imagesy().
If you mean filesize, that's not possible without converting the GD resource to some image format (GIF, PNG, JPEG) because the format determines the image size in bytes.
I doubt you can since php gd image object is a generic object, without considerations on the compression that will be used for storage (png/jpg/bmp ...)

Categories