I want to get the resolution of an AI file but it only returns 72. However, the resolution is supposed to be 300. If I were to change the resolution of the image using imagick, it would come out to be something far less [the dimensions]. How can I get the actual resolution of a file?
In case I can't use imagick for that, is there a library or framework that can give me the precised resolution of a file (regardless what type)?
I have my code as:
try {
$imagick = new Imagick($imagePath);
$data = $imagick->identifyimage();
}
catch(Exception $e) {
echo json_encode('ERROR: ' . $e->getMessage());
}
if($data['units'] == 'PixelsPerCentimeter') {
$imageResolution = $imagick->getImageResolution(); // Temp Image Resolution
//echo 'pixels per cent lol';
if (!empty($imageResolution['y'])) {
$dpi = intval( round($imageResolution['y'] * 2.54, 2) );
}
}
else $dpi = $data['resolution']['x'];
$width = round($data['geometry']['width'] / $dpi, 3);
$height = round($data['geometry']['height'] / $dpi, 3);
Related
My application allows users to upload bunch of images which are later sent as an email attachment. The problem shows up if file size of images that are being sent is bigger than email accept.
What I want to do is to reduce file size of image until it is lower then 5MB and this is how I tried to do it:
/*..some code...*/
$img_quality = 75;
while (filesize($path) >= 5242880) {
$img_string = file_get_contents($path);
$img = imagecreatefromstring($img_string);
$path = $this->getFilePath($file, $file_section, $entity_id);
imagejpeg($img, $path, $img_quality);
$img_quality--;
}
/*..some code...*/
//Functions I am calling
public function getFilePath($upload, $section, $id = null) {
$path = base_path('../upload').$this->downloadOverwrite($upload, $section, $id);
if(!$upload) {
return $path;
}
if(!file_exists($path)) {
return null;
}
$tmppath = #tempnam("tmp", "myapp");
file_put_contents($tmppath, file_get_contents($path));
return $tmppath;
}
public function downloadOverwrite($upload, $section, $id = null, $config = []) {
$section = !empty($upload['entity']) ? $upload['entity'] : $section;
$id = !empty($upload['entity_id']) ? $upload['entity_id'] : $id;
$path = empty($id) ? "/$section" : "/$section/$id";
if(!empty($upload)) $path .= "/{$upload['fs_name']}";
return $path;
}
This code actually works, but if image file size is too big, it takes too long before image is compressed to desired value. Is there any better solution to do this?
actually yes there is a package which is really popular for manipulating images in php which has good integration with laravel :
http://image.intervention.io/getting_started/installation
so with this package you do as below :
$ php composer.phar require intervention/image
and after adding aliases if laravel < 5.5 you publish vendor files :
$ php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravelRecent"
then you can replace image handling to this :
// create instance
$img = Image::make('public/foo.jpg');
// resize image to fixed size
$img->resize(300, 200);
to resize or do any thing like prevent upsizing like :
// prevent possible upsizing
$img->resize(null, 400, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
});
or any thing you would like to do according to documentation .
hope this helps
In case someone has similiar problem, here is the loop that I used in the end and that worked pretty well for me. May not be the best solution out there, but it's fair enough:
$image_width = getimagesize($path)[0];
while (filesize($path) >= 5242880) {
$image_width -= 50;
$img_string = file_get_contents($path);
$img = imagecreatefromstring($img_string);
$path = $this->getFilePath($file, $file_section, $entity_id);
$img = imagescale($img, $image_width);
imagejpeg($img, $path);
}
I am lowering the width of the image, while height is being lowered automatically respecting the aspect ratio. This results in pretty fast file size drop, while keeping the quality of image at approximately the same level as it was before scaling.
Background:
I have been working on an issue whereby a file upload form will only accept certain images, it is not a problem with image size(dimensions) or with size(filesize) but I think i've found it's to do with image bit depth, as the PHP script resizes the image and applies a static (semi-transparant) watermark file to the image and saves the result.
I have gone through a long process today and yesterday working with this as the error that occurs is the server stating "Connection reset by server" . Which I think I've narrowed down to the server not having enough free memory to complete the image resource manipulations.
Issue:
Then, after all that, this error comes up on file upload submission:
IPS detected for "WEB PHP EXIF Process IFD TAG Remote Integer Overflow -2 (CVE-20/Buffer Over Flow"
Some googling only tells me that it's a securty vulnerabiliy for PHP < 4.2 or so, and doesn't relate to actually what's going on.
I have looked through my code and am very sure that
My query is to try and shed some light on what this error statement means (and how I can go about correcting it)?
Notes:
PHP 5.6.16
No PHP EXIF functions run on the page.
I can't see anywhere on the page that would cause an integer overflow (running to infinity, I guess)
Page does use imagecopy, imagealphablending and imagesavealpha But this error notice seems to appear before the script runs on the uploaded file.
This error only occurs on some uploaded images and not on others.
I have found no Apache error logs relating to this
I have no PHP errors recorded.
Code:
As I think the issue may occur somehow before the page loads I'm not sure how useful this code block will be but, take a look:
(also please note that I am aware this page is 5 years old and isn't the smartest programming, i have fixed it up in parts but am aware it can probably be further tidied)
<?php
session_start();
error_reporting(E_ALL);
ini_set('display_errors', 1);
///first set out variables.
$goodImage = 0;
$maxfilesize = (int)$_POST['MAX_FILE_SIZE'];
$gallery = (int)$_POST['galfolderid']
if (empty($gallery)) {
$_SESSION['message'] = $gallery . "<br/>Gallery Value has not been set.";
}
elseif (!is_numeric($gallery)) {
$_SESSION['message'] = $gallery . "<br/>Gallery Value is not a numeric value.";
}
elseif (!is_dir($_SERVER['DOCUMENT_ROOT']."/images/gallery/" . $gallery )) {
$_SESSION['message'] = $gallery . "<br/>Gallery Value, while being a number, is not a valid numeric value.";
}
if(!empty($_SESSION['message'])) {
header("Location:editgallery.php?gallery=".$galleryid);
exit;
}
for($count=0;$count<5;$count++) {
if ($_FILES['image']['error'][$count] == 0) {
clearstatcache();
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$imageType = finfo_file($finfo, $_FILES['image']['tmp_name'][$count]);
finfo_close($finfo);
unset($finfo);
if (strtolower($imageType) == "image/png") {
$imgtype = "PNG";
$original = imagecreatefrompng($_FILES['image']['tmp_name'][$count]);
} elseif (strtolower($imageType) == "image/jpeg" || strtolower($imageType) == "image/jpg") {
$imgtype = "JPG";
$original = imagecreatefromjpeg($_FILES['image']['tmp_name'][$count]);
} else {
//not a JPG or PNG type... set error.
$_SESSION['message'] = "Image " . ($count+1) . " does not appear to be a valid .JPG or .PNG file. ";
error_log($_SESSION['message']);
header("Location:editgallery.php");
exit;
}
unlink($_FILES['image']['tmp_name'][$count]);
$edgePadding = (int)$_POST['WMedge'][$count]; //integer
$watermarkScale = $_POST['WMscale'][$count]; //float
$h_position = $_POST['Hpos'][$count]; //text array
$v_position = $_POST['Vpos'][$count]; //text array
$Hoz = $h_position[0];
$Vez = $v_position[0];
if (!isset($watermarkScale) || empty($watermarkScale) || !is_numeric($watermarkScale)) {
$watermarkScale = 1.0;
}
elseif($watermarkScale > 2.0) {
$watermarkScale = 2.0;
}
elseif($watermarkScale < 0.5) {
$watermarkScale = 0.5;
}
if ((!isset($edgePadding) || empty($edgePadding) || !is_numeric($edgePadding)) && $edgePadding !== "0") {
$edgePadding = 5;
}
// be sure that the other options we need have some kind of value
if ($_FILES['image']['size'][$count] > $maxfilesize) {
$_SESSION['message'] .= "Image file ".($count+1)." appears to be too big. There is a limit of 2Mb on the
size of the image you can upload. Please click 'Back' on your browser and resubmit a valid image.";
error_log($_SESSION['message']);
//file too big.
}
//target name is the number of images in the LARGE gallery,
///cycle through imagenames to find the first "clear" image number.
$newimagename = 1;
clearstatcache();
/***
NOTE: Only possible place an integer oveflow might occur I think
***/
while (file_exists($_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $gallery . "/S/" . $newimagename . ".jpg")) {
$newimagename++;
}
///newimagename is the new filename of the image.
$target_name = $newimagename . ".jpg";
$target = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $gallery . "/L/" . $target_name;
$targetSmall = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $gallery . "/S/" . $target_name;
//targetSM is used below to make the thumbnail image. for the SMALL gallery.
//full target directory and name.
// file upload success
// now file need resizing before the watermark is applied.
// resize new dimensions (Large- 800px)
$originalImageSize[0] = imagesx($original);
$originalImageSize[1] = imagesy($original);
/***
* Resize new dimensions for small thumbnail.
***/
if ($originalImageSize[0] > 133) {
$percent = 133 / $originalImageSize[0];
} else {
$percent = 1;
}
$newThumbHeight = $originalImageSize[1] * $percent;
$newThumbWidth = $originalImageSize[0] * $percent;
// Resample
$imageThumbFinal = imagecreatetruecolor($newThumbWidth, $newThumbHeight);
imagecopyresampled($imageThumbFinal, $original, 0, 0, 0, 0, $newThumbWidth, $newThumbHeight, $originalImageSize[0], $originalImageSize[1]);
// Output
imagejpeg($imageThumbFinal, $targetSmall, 80);
imagedestroy($imageThumbFinal);
unset($imageThumbFinal, $percent,$newThumbWidth,$newThumbHeight);
/***
* End Thumbnail generation.
*/
/***
* Resize main sized image (max 800px wide)
***/
if ($originalImageSize[0] > 800) {
$percent = 800 / $originalImageSize[0];
} else {
$percent = 1;
}
$newPictureHeight = $originalImageSize[1] * $percent;
$newPictureWidth = $originalImageSize[0] * $percent;
// Resample main image to reduce max size.
$imageCleanFinal = imagecreatetruecolor($newPictureWidth, $newPictureHeight);
imagecopyresampled($imageCleanFinal, $original, 0, 0, 0, 0, $newPictureWidth, $newPictureHeight, $originalImageSize[0], $originalImageSize[1]);
/***
* Now resize the watermark and save onto the final image.
***/
//full target directory and name.
$watermark = $_SERVER['DOCUMENT_ROOT'] . "/images/watermark2.png";
$wmTarget = substr($watermark, 0, -3) . "tmp"; //image/watermark2.tmp is resized.
$sourceWaterImage = imagecreatefrompng($watermark);
$waterMarkWidth = imagesx($sourceWaterImage);
$waterMarkHeight = imagesy($sourceWaterImage);
$destinationHeight = $waterMarkHeight * $watermarkScale;
$destinationWidth = $waterMarkWidth * $watermarkScale;
$destinationHeight = floor($destinationHeight);
$destinationWidth = floor($destinationWidth);
$destinationWatermarkImage = imagecreatetruecolor($destinationWidth, $destinationHeight);
imagealphablending($destinationWatermarkImage, FALSE);
imagesavealpha($destinationWatermarkImage, TRUE);
imagecopyresampled($destinationWatermarkImage, $sourceWaterImage, 0, 0, 0, 0, $destinationWidth,
$destinationHeight, $waterMarkWidth, $waterMarkHeight);
imagedestroy($sourceWaterImage);
unset($sourceWaterImage);
clearstatcache();
/***
* Set watermark location on final image.
***/
$differenceX = $newPictureWidth - $destinationWidth;
$differenceY = $newPictureHeight - $destinationHeight;
switch ($Hoz) {
// find the X coord for placement
case 'left':
$placementX = $edgePadding;
break;
case 'center':
$placementX = round($differenceX / 2);
break;
case 'right':
$placementX = $newPictureWidth - ($destinationWidth + $edgePadding);
break;
default:
$placementX = 0;
break;
}
switch ($Vez) {
// find the Y coord for placement
case 'top':
$placementY = $edgePadding;
break;
case 'middle':
$placementY = round($differenceY / 2);
break;
case 'bottom':
$placementY = $newPictureHeight - ($destinationHeight + $edgePadding);
break;
default:
$placementY = 0;
break;
}
/***
* Finish set Watermark location
***/
imagecopy($imageCleanFinal,
$destinationWatermarkImage,
$placementX,
$placementY,
0,
0,
$destinationWidth,
$destinationHeight);
imagejpeg($imageCleanFinal, $target, 80);
/***
* Image final save
***/
// Output
imagejpeg($imageCleanFinal, $target, 80);
imagedestroy($imageCleanFinal);
imagedestroy($destinationWatermarkImage);
unset($imageCleanFinal, $percent);
unlink($wmTarget);
$output[$goodImage]['targetName'] = $target_name;
$output[$goodImage]['targetAddr'] = $target;
$goodImage++;
} elseif (!isset($_FILES['image']['name'][$count]) || ($_FILES['image']['error'][$count] != 0 && $_FILES['image']['error'][$count] != 4)) {
//error in file upload.
$_SESSION['message'] .= " There is a file upload error number " . $_FILES['image']['error'][$count] . ". for image ".($count+1).".
Please try resubmitting a valid image.";
error_log($_SESSION['message']);
}
}
if (empty($_SESSION['message'])){
$_SESSION['message'] = $goodImage." New Image(s) Uploaded";
}
// display resulting image for download
header("Location:editgallery.php?special=yes&gallery=".$galleryid);
exit;
Server Details:
Apache 2.4
WebHostManger & CPanel (combined) version 54.0.19
PHP 5.6 using Mod suPHP 0.7.2
2 core 2.2GHz (so x2) intel with
1896Mb/2097Mb physical memory (used/available)
+4095Mb memory Swap File. (~6010Mb total)
I have a function that uploads files up to 8MB but now I also want to compress or at least rescale larger images, so my output image won't be any bigger than 100-200 KB and 1000x1000px resolution. How can I implement compress and rescale (proportional) in my function?
function uploadFile($file, $file_restrictions = '', $user_id, $sub_folder = '') {
global $path_app;
$new_file_name = generateRandomString(20);
if($sub_folder != '') {
if(!file_exists('media/'.$user_id.'/'.$sub_folder.'/')) {
mkdir('media/'.$user_id.'/'.$sub_folder, 0777);
}
$sub_folder = $sub_folder.'/';
}
else {
$sub_folder = '';
}
$uploadDir = 'media/'.$user_id.'/'.$sub_folder;
$uploadDirO = 'media/'.$user_id.'/'.$sub_folder;
$finalDir = $path_app.'/media/'.$user_id.'/'.$sub_folder;
$fileExt = explode(".", basename($file['name']));
$uploadExt = $fileExt[count($fileExt) - 1];
$uploadName = $new_file_name.'_cache.'.$uploadExt;
$uploadDir = $uploadDir.$uploadName;
$restriction_ok = true;
if(!empty($file_restrictions)) {
if(strpos($file_restrictions, $uploadExt) === false) {
$restriction_ok = false;
}
}
if($restriction_ok == false) {
return '';
}
else {
if(move_uploaded_file($file['tmp_name'], $uploadDir)) {
$image_info = getimagesize($uploadDir);
$image_width = $image_info[0];
$image_height = $image_info[1];
if($file['size'] > 8000000) {
unlink($uploadDir);
return '';
}
else {
$finalUploadName = $new_file_name.'.'.$uploadExt;
rename($uploadDirO.$uploadName, $uploadDirO.$finalUploadName);
return $finalDir.$finalUploadName;
}
}
else {
return '';
}
}
}
For the rescaling I use a function like this:
function dimensions($width,$height,$maxWidth,$maxHeight)
// given maximum dimensions this tries to fill that as best as possible
{
// get new sizes
if ($width > $maxWidth) {
$height = Round($maxWidth*$height/$width);
$width = $maxWidth;
}
if ($height > $maxHeight) {
$width = Round($maxHeight*$width/$height);
$height = $maxHeight;
}
// return array with new size
return array('width' => $width,'height' => $height);
}
The compression is done by a PHP function:
// set limits
$maxWidth = 1000;
$maxHeight = 1000;
// read source
$source = imagecreatefromjpeg($originalImageFile);
// get the possible dimensions of destination and extract
$dims = dimensions(imagesx($source),imagesy($source),$maxWidth,$maxHeight);
// prepare destination
$dest = imagecreatetruecolor($dims['width'],$dims['height']);
// copy in high-quality
imagecopyresampled($dest,$source,0,0,0,0,
$width,$height,imagesx($source),imagesy($source));
// save file
imagejpeg($dest,$destinationImageFile,85);
// clear both copies from memory
imagedestroy($source);
imagedestroy($dest);
You will have to supply $originalImageFile and $destinationImageFile. This stuff comes from a class I use, so I edited it quite a lot, but the basic functionality is there. I left out any error checking, so you still need to add that. Note that the 85 in imagejpeg() denotes the amount of compression.
you can use a simple one line solution through imagemagic library the command will like this
$image="path to image";
$res="option to resize"; i.e 25% small , 50% small or anything else
exec("convert ".$image." -resize ".$res." ".$image);
with this you can rotate resize and many other image customization
Take a look on imagecopyresampled(), There is also a example that how to implement it, For compression take a look on imagejpeg() the third parameter helps to set quality of the image, 100 means (best quality, biggest file) and if you skip the last option then default quality is 75 which is good and compress it.
I'm using PHP Imagick to resize images at runtime. The site has an image upload feature and we can't trust the user to use web-friendly JPEGs, as during the mass-import there are many 3 to 5MB images, and even a few as large as 13MB. Each image gets turned into a thumbnail (200x200), and when going from list view into detailed view only one image is shown, so performance isn't a huge deal although we can't completely throw it by the wayside. Here's what we're doing so far:
$iMagick = new Imagick($file);
$iMagick->setImageResolution(72,72);
$iMagick->resampleImage(72,72,imagick::FILTER_UNDEFINED,1);
$geometry = $iMagick->getImageGeometry();
if ($geometry['height'] > 1920 || $geometry['width'] > 1080) {
$iMagick->scaleImage(1920, 0);
if($geometry['height'] > $resizeHeight) {
$iMagick->scaleImage(0, 1080);
}
}
$iMagick->setImageCompression(Imagick::COMPRESSION_JPEG);
$iMagick->setImageCompressionQuality($compression);
$iMagick->writeImage($file);
$Imagick->clear();
Side note: I just realized the flaw in my conditional logic here about height/width, so ignore that for the time being. I'll edit the question soon to reflect the correct condition comparisons. For those who didn't catch it it's scaling all images to 1920 wide even if it's supposed to be scaling the height, then after the scale it's sizing it back down to 1080 height.
The image I've used to test starts as a 3MB 2398×2400 image. Scaling it to 1079x1080 results in a 1.5MB image, then adding JPEG compression at quality 70 brings it down to 750KB. Using kraken.io the image was able to be compressed to just under 60KB. Are there any additional things I can do to this script since it needs to optimize the image at runtime?
I've read suggestions to use libjpeg, which is installed, but I can't find any documentation on what functions it enables or if there's a way to force Imagick to use it specifically. I'm not even sure that Imagick isn't using it already.
Edit: Solution
function itm_optimizeImage($file, $compression = 70, $maxDimensions = ['width' => null, 'height' => null]) {
$save = false;
$fi = new finfo(FILEINFO_MIME);
$mime = explode(';', $fi->file($file));
switch ($mime[0]) {
// possible to optimize other image types in the future
case 'image/jpeg':
try {
$iMagick = new Imagick($file);
if ($iMagick->getImageCompressionQuality() > $compression) {
$file = !itm_compressJPEG($file, $compression, $maxDimensions, $iMagick);
}
}
catch (Exception $e) {
error_log(__FUNCTION__ . " $path/$file failed: " . $e->getMessage());
return false;
}
if ($file) {
$pathParts = pathinfo($file);
rename($file, $pathParts['dirname'] . '/' . $pathParts['filename'] . '.large.' . $pathParts['extension']);
$iMagick->writeImage($file);
}
$iMagick->clear();
break;
}
return $file;
}
function itm_compressJPEG($file, $compression = 70, $maxDimensions = ['width' => null, 'height' => null], &$iMagick = null) {
try {
$iMagickCreated = true;
if ($iMagick) $iMagickCreated = false;
else $iMagick = new Imagick($file);
$iMagick->setImageResolution(72,72);
$iMagick->resampleImage(72,72,imagick::FILTER_UNDEFINED,1);
$geometry = $iMagick->getImageGeometry();
if (($geometry['width'] / $maxDimensions['width']) > ($geometry['height'] / $maxDimensions['height'])) {
// scale by width
$iMagick->scaleImage($maxDimensions['width'], 0);
} else {
// scale by height
$iMagick->scaleImage(0, $maxDimensions['height']);
}
$iMagick->setImageCompression(Imagick::COMPRESSION_JPEG);
$iMagick->setImageCompressionQuality($compression);
$iMagick->setImageFormat('jpg');
$iMagick->stripImage();
if ($iMagickCreated) {
$pathParts = pathinfo($file);
rename($file, $pathParts['dirname'] . '/' . $pathParts['filename'] . '.large.' . $pathParts['extension']);
$iMagick->writeImage($file);
$Imagick->clear();
}
return $file;
}
catch (Exception $e) {
error_log(__FUNCTION__ . " $path/$file failed: " . $e->getMessage());
return false;
}
}
Set the setImageCompressionQuality to a value of 70 and add these two lines after it.
$image->setImageFormat("jpg");
$image->stripImage();
This will dramatically reduce the size of the images.
I just discovered this article http://jeffkreeftmeijer.com/2011/comparing-images-and-creating-image-diffs/
It is talking about using regular Ruby and ChunkyPNG to do image diffs.
In particular, the first code of doing a loop through all the pixels.
require 'chunky_png'
images = [
ChunkyPNG::Image.from_file('1.png'),
ChunkyPNG::Image.from_file('2.png')
]
diff = []
images.first.height.times do |y|
images.first.row(y).each_with_index do |pixel, x|
diff << [x,y] unless pixel == images.last[x,y]
end
end
puts "pixels (total): #{images.first.pixels.length}"
puts "pixels changed: #{diff.length}"
puts "pixels changed (%): #{(diff.length.to_f / images.first.pixels.length) * 100}%"
x, y = diff.map{ |xy| xy[0] }, diff.map{ |xy| xy[1] }
images.last.rect(x.min, y.min, x.max, y.max, ChunkyPNG::Color.rgb(0,255,0))
images.last.save('diff.png')
I wonder
a) what would be an ideal PHP equivalent of ChunkyPNG?
b) what would be the implementation of the same code in PHP?
You can do with Imagick extension. Imagick is a native php extension to create and modify images using the ImageMagick API.
Example Using Imagick::compareImages():
Compare images and display the reconstructed image.
<?php
$image1 = new imagick("image1.png");
$image2 = new imagick("image2.png");
$result = $image1->compareImages($image2, Imagick::METRIC_MEANSQUAREERROR);
$result[0]->setImageFormat("png");
header("Content-Type: image/png");
echo $result[0];
?>
OR
A PHP shell script to tell you if two images are visually different by comparing them pixel by pixel. If there's a difference, the script creates a third image - black background with the different pixels in green. Here two GD images are created from the input files, also a third GD image with black background to store the diff. Loop through all the pixels and compare them one by one. If one is different, write a green pixel at the same location of the diff image. [Source : http://www.phpied.com/image-diff/ ]
diff.php
<?php
/**
* Shell script to tell if two images are identical.
* If not, a third image is written - black background with the different pixels painted green
* Code partially inspired by and borrowed from http://pear.php.net/Image_Text test cases
*/
// check if there's enough input
if (empty($argv[1]) || empty($argv[2])) {
echo 'gimme at least two image filenames, please.', "\n";
echo 'e.g. "php idiff.php img1.png img2.png"';
echo "\n", 'third filename is the image diff, optional, default is "diffy.png"';
exit(1);
}
// create images
$i1 = #imagecreatefromstring(file_get_contents($argv[1]));
$i2 = #imagecreatefromstring(file_get_contents($argv[2]));
// check if we were given garbage
if (!$i1) {
echo $argv[1] . ' is not a valid image';
exit(1);
}
if (!$i2) {
echo $argv[2] . ' is not a valid image';
exit(1);
}
// dimensions of the first image
$sx1 = imagesx($i1);
$sy1 = imagesy($i1);
// compare dimensions
if ($sx1 !== imagesx($i2) || $sy1 !== imagesy($i2)) {
echo "The images are not even the same size";
exit(1);
}
// create a diff image
$diffi = imagecreatetruecolor($sx1, $sy1);
$green = imagecolorallocate($diffi, 0, 255, 0);
imagefill($diffi, 0, 0, imagecolorallocate($diffi, 0, 0, 0));
// increment this counter when encountering a pixel diff
$different_pixels = 0;
// loop x and y
for ($x = 0; $x < $sx1; $x++) {
for ($y = 0; $y < $sy1; $y++) {
$rgb1 = imagecolorat($i1, $x, $y);
$pix1 = imagecolorsforindex($i1, $rgb1);
$rgb2 = imagecolorat($i2, $x, $y);
$pix2 = imagecolorsforindex($i2, $rgb2);
if ($pix1 !== $pix2) { // different pixel
// increment and paint in the diff image
$different_pixels++;
imagesetpixel($diffi, $x, $y, $green);
}
}
}
if (!$different_pixels) {
echo "Image is the same";
exit(0);
} else {
if (empty($argv[3])) {
$argv[3] = 'diffy.png'; // default result filename
}
imagepng($diffi, $argv[3]);
$total = $sx1 * $sy1;
echo "$different_pixels/$total different pixels, or ", number_format(100 * $different_pixels / $total, 2), '%';
exit(1);
}
?>
Usage (Command line):
php diff.php img1.png img2.png result.png