在php中比较2个图像

时间:2010-07-17 09:31:53

标签: php image gd compare md5

比较2个图像以查看它们是否是相同的文件很容易,抛出文件MD5,但是通过使用PHP GD来确定两个图像的差异是否有可能甚至是合理的来确定2个图像是否相同。如果我们在哪里得到两者的差异,并且它全是白色(id假设为白色甚至是黑色),那么我们现在就知道它们的相同照片了吗?

另外注意:id想知道是否可以获得2张相同大小的图像来创建洋葱皮效果,1%和50%透明度为50%。

8 个答案:

答案 0 :(得分:18)

ImageMagick通过PHP ImageMagick扩展提供了各种可用于此的工具。

http://www.php.net/manual/en/function.imagick-compareimages.php

最大的问题是该库的文档几乎不存在,因此会涉及大量的反复试验。

答案 1 :(得分:15)

$md5image1 = md5(file_get_contents($image1));
$md5image2 = md5(file_get_contents($image2));
if ($md5image1 == $md5image2) {

}

答案 2 :(得分:9)

libpuzzle是一个可以比较图像的PHP扩展。

答案 3 :(得分:3)

Stackoverflow thread 上提出了类似的问题,我已经为自己开发了一些东西。在此发布,以便它可以帮助他人。

它需要两个(或更多图像),并为您提供有关检查它们之间差异的选项。选项如使用分辨率和严格性。

我写了一篇更全面的 blogpost on it as well

答案 4 :(得分:3)

PHP与GD库中的图像比较功能 http://www.robert-lerner.com/imagecompare.php

答案 5 :(得分:0)

不确定是否那么容易并且解决方案退出但是您可能从以下方面了解图像检测:

Face detection with PHP
Image Nudity Filter (Class)

答案 6 :(得分:0)

如果您只比较两个文件然后散列数据然后比较是完美的解决方案。如果您要比较大量文件,那么首先根据大小对它们进行排序,然后仅比较相同的大小。

答案 7 :(得分:0)

我使用PHP中已经包含的GD Graphics Library编写了一种均方误差比较方法。

我担心时间,所以我加入了一些选择,例如:

但是要查看结果,如果您要进行批量操作,最好的方法是硬编码来避免条件行的 overhead 开销。

这是代码,带有一些 test 和一个 benchmark

<?php
define('FILENAME1','./image1.png'); 
define('FILENAME2','./image2.png');    
define('OUTEXT','png'); //Output extension
    
/**
 * Calculate an arbitrary metric of difference between images
 * 
 * @param resource(gd) $img1 First image
 * @param resource(gd) $img2 Second image
 * @param int $resX Scaled width resolution
 * @param int $resY Scaled height resolution
 * @param int $pow Mean square error if 2, but could be another power
 * @param string $channel RGB channel or 'all' for perceived luminance
 *
 * @return float the calculated metric
 */
function diff($img1,$img2,$resX=false,$resY=false,$pow='2',$channel='all'){ 
    //Scaling to image 1 size for default
    if(!$resX||!$resY){     
        $resX=imagesx($img1); //width
        $resY=imagesy($img2); //height
    }
    //Use imagescale() function to scale the images 
    $thumb1=imagescale($img1,$resX,$resY);
    $thumb2=imagescale($img2,$resX,$resY);
    //Sum of errors
    $sum=0;
    for($x=0;$x<$resX;++$x){
        for($y=0;$y<$resY;++$y){
            //Read pixel bytes
            $bytes1=imagecolorat($thumb1,$x,$y);
            $bytes2=imagecolorat($thumb2,$x,$y);
            //Split the channel values from bytes
            $colors1=imagecolorsforindex($thumb1,$bytes1);
            $colors2=imagecolorsforindex($thumb2,$bytes2);
            //Choose image channel
            if($channel=='all'){
                //Perceived luminance
                $value1=sqrt(0.2126*$colors1['red']**2+0.7152*$colors1['green']**2+ 0.0722*$colors1['blue']**2);
                $value2=sqrt(0.2126*$colors2['red']**2+0.7152*$colors2['green']**2+ 0.0722*$colors2['blue']**2);
            }else{
                //RGB channel
                $value1=$colors1[$channel];
                $value2=$colors2[$channel];
            }
            $sum+=abs($value1-$value2)**$pow;           
        }
    }
    //Return mean of the error sum
    return $sum/($resX*$resY);
}

//Show image in HTML
function imgdraw($imgobj){      
    //Choose function
    $image="image".OUTEXT;
    //Capture the image data stream     
    ob_start();     
    $image($imgobj);        
    $data = ob_get_clean();     
    //Create and HTML img
    echo '<img src="data:image/png;base64,'.base64_encode($data).'" />';
}

//Load an image
function loadimg($filename){
    //Get filename extension
    $ext=substr($filename,strrpos($filename,'.')+1);
    //Create image object
    $imagecreate="imagecreatefrom$ext";
    return $imagecreate($filename);
}

//Test 
$img1=loadimg(FILENAME1);
$img2=loadimg(FILENAME2);
if( !$img1 || !$img2){
    //Problem reading the files
    die("Error loading image files");
}else{
    imgdraw($img1);
    imgdraw($img2);
}

//Times for 133x144 pixels png images
echo "<p>original size MSE perceived luminance: ".diff($img1,$img2)."</p>";
//time: 0.2281 seconds.
echo "<p>original size MSE green channel: ".diff($img1,$img2,false,false,2,'green')."</p>";
//time: 0.1364 seconds.
echo "<p>original size linear perceived luminance: ".diff($img1,$img2,false,false,1)."</p>";
//time: 0.1920 seconds.
echo "<p>original size linear green channel: ".diff($img1,$img2,false,false,1,'green')."</p>";
//time: 0.1351 seconds.
echo "<p>64x64 MSE perceived luminance: ".diff($img1,$img2,64,64)."</p>";
//time: 0.0431 seconds.
echo "<p>64x64 MSE green channel: ".diff($img1,$img2,64,64,2,'green')."</p>";
//time: 0.0293 seconds.
echo "<p>64x64 linear perceived luminance: ".diff($img1,$img2,64,64,1)."</p>";
//time: 0.0423 seconds.
echo "<p>64x64 linear green channel: ".diff($img1,$img2,64,64,1,'green')."</p>";
//time: 0.0293 seconds.
echo "<p>16x16 MSE perceived luminance: ".diff($img1,$img2,16,16)."</p>";
//time: 0.0028 seconds.
echo "<p>16x16 MSE green channel: ".diff($img1,$img2,16,16,2,'green')."</p>";
//time: 0.0027 seconds.
echo "<p>16x16 linear perceived luminance: ".diff($img1,$img2,16,16,1)."</p>";
//time: 0.0027 seconds.
echo "<p>16x16 linear green channel: ".diff($img1,$img2,16,16,1,'green')."</p>";
//time: 0.0018 seconds.
?>