0

I want to compare the uploaded pic with all images in database, if it is matching then should display details of matched image.

I have tried this but couldn't understand, can anyone help with different one?

<?php
class compareImages
{
    private function mimeType($i)
    {
        /*returns array with mime type and if its jpg or png. Returns false if it isn't jpg or png*/
        $mime = getimagesize($i);
        $return = array($mime[0],$mime[1]);

        switch ($mime['mime'])
        {
            case 'image/jpeg':
                $return[] = 'jpg';
                return $return;
            case 'image/png':
                $return[] = 'png';
                return $return;
            default:
                return false;
        }
    }  

    private function createImage($i)
    {
        /*retuns image resource or false if its not jpg or png*/
        $mime = $this->mimeType($i);

        if($mime[2] == 'jpg')
        {
            return imagecreatefromjpeg ($i);
        } 
        else if ($mime[2] == 'png') 
        {
            return imagecreatefrompng ($i);
        } 
        else 
        {
            return false; 
        } 
    }

    private function resizeImage($i,$source)
    {
        /*resizes the image to a 8x8 squere and returns as image resource*/
        $mime = $this->mimeType($source);

        $t = imagecreatetruecolor(8, 8);

        $source = $this->createImage($source);

        imagecopyresized($t, $source, 0, 0, 0, 0, 8, 8, $mime[0], $mime[1]);

        return $t;
    }

    private function colorMeanValue($i)
    {
        /*returns the mean value of the colors and the list of all pixel's colors*/
        $colorList = array();
        $colorSum = 0;
        for($a = 0;$a<8;$a++)
        {

            for($b = 0;$b<8;$b++)
            {

                $rgb = imagecolorat($i, $a, $b);
                $colorList[] = $rgb & 0xFF;
                $colorSum += $rgb & 0xFF;

            }

        }

        return array($colorSum/64,$colorList);
    }

    private function bits($colorMean)
    {
        /*returns an array with 1 and zeros. If a color is bigger than the mean value of colors it is 1*/
        $bits = array();

        foreach($colorMean[1] as $color){$bits[]= ($color>=$colorMean[0])?1:0;}

        return $bits;

    }

    public function compare($a,$b)
    {
        /*main function. returns the hammering distance of two images' bit value*/
        $i1 = $this->createImage($a);
        $i2 = $this->createImage($b);

        if(!$i1 || !$i2){return false;}

        $i1 = $this->resizeImage($i1,$a);
        $i2 = $this->resizeImage($i2,$b);

        imagefilter($i1, IMG_FILTER_GRAYSCALE);
        imagefilter($i2, IMG_FILTER_GRAYSCALE);

        $colorMean1 = $this->colorMeanValue($i1);
        $colorMean2 = $this->colorMeanValue($i2);

        $bits1 = $this->bits($colorMean1);
        $bits2 = $this->bits($colorMean2);

        $hammeringDistance = 0;

        for($a = 0;$a<64;$a++)
        {

            if($bits1[$a] != $bits2[$a])
            {
                $hammeringDistance++;
            }

        }

        return $hammeringDistance;
    }
}
?>
RPichioli
  • 3,245
  • 2
  • 25
  • 29
  • 2
    quickest way to compare, to check if two files are identical, could be using md5 hash of the files and comparing them. However, I'm not sure if this is the best approach though. –  Dec 06 '16 at 11:13
  • you can do this using php **ImageMagick** (Image Processing) library and use its **Imagick::compareImages** function. link: http://sg2.php.net/manual/en/imagick.compareimages.php – Soni Vimalkumar Dec 06 '16 at 11:19
  • http://stackoverflow.com/a/13758760/4248328 and then compare – Alive to die - Anant Dec 06 '16 at 11:20
  • Maybe http://stackoverflow.com/q/843972/1741542 – Olaf Dietsche Dec 06 '16 at 11:26

3 Answers3

3

If you're using php 8.1 or higher, you can use https://github.com/sapientpro/image-comparator library for that. It is capable to compare multiple images:

$comparator = new SapientPro\ImageComparator\ImageComparator();

$similaritues = $comparator->compareArray(
'uploaded_pic.jpg',
[
  'image1.jpg',
  'image2.jpg',
  'image3.jpg',
  ...
]
)

echo $similarities; // [100.00, 43.3, 79.2, ...]
  • Neat library. I'd note that this may take significant time to execute with a lot of images; you'd probably want to store the hashes for later use. – ceejayoz May 19 '23 at 12:08
0

actually you can using md5 has of the files as mention in previous comment or you can convert the images into base64 string and compare between base64 string. base64string will return same pattern if you have two identical images

good luck

Evinn
  • 153
  • 1
  • 11
0

Try this:maybe helpful

<?php
$sourceImagepath = encodeImage("folder/source.png");
$uploadedImagepath = encodeImage("temp/uploded.png");

if(areEqual($sourceImagepath , $uploadedImagepath)){
    echo "Image is already Exist";
    return false;
}
echo "Image Upload";


function encodeImage($ImagePath){
    $ext = pathinfo($ImagePath, PATHINFO_EXTENSION);
    $Imgcontent = file_get_contents($ImagePath);
    $base64 = 'data:image/' . $ext . ';base64,' . base64_encode($Imgcontent);
    return $base64;
}

function areEqual($sourceImage, $uploadedImage){    
    if (strcmp($sourceImage, $uploadedImage) !== 0) {
            return false;
    }
    return true;
}
?>

OR

<?php 

    function areEqual($firstPath, $secondPath, $chunkSize = 500){

        // First check if file are not the same size as the fastest method
        if(filesize($firstPath) !== filesize($secondPath)){
            return false;
        }

        // Compare the first ${chunkSize} bytes
        // This is fast and binary files will most likely be different 
        $fp1 = fopen($firstPath, 'r');
        $fp2 = fopen($secondPath, 'r');
        $chunksAreEqual = fread($fp1, $chunkSize) == fread($fp2, $chunkSize);
        fclose($fp1);
        fclose($fp2);

        if(!$chunksAreEqual){
            return false;
        }

        // Compare hashes
        // SHA1 calculates a bit faster than MD5
        $firstChecksum = sha1_file($firstPath);
        $secondChecksum = sha1_file($secondPath);
        if($firstChecksum != $secondChecksum){
            return false;
        }

        return true;
    }
    ?>
Soni Vimalkumar
  • 1,449
  • 15
  • 26
  • thanks its working , but sorry for extending doubt .... what if i want to accept similar images also like, same object(in image) with different color , rotated , compresses . – Sudheer Kumar Akon Dec 07 '16 at 17:21
  • if its work than please mark the answer and upvote it so other developers can easily find the solutions. – Soni Vimalkumar Dec 08 '16 at 03:03