【问题标题】:Compare 2 images in php在php中比较2张图片
【发布时间】:2011-03-17 07:15:46
【问题描述】:

比较两张图片看它们是否是相同的文件很容易,扔文件 MD5,但是否有可能甚至是合理的,通过使用 PHP GD 来确定两张图片是否相同来获得两张图片的差异。如果我们从哪里得到两者的区别,而且都是白色的(假设是白色甚至是黑色),那么我们现在就知道它是同一张照片了吗?

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

【问题讨论】:

  • 还需要透明效果吗?我回答了标题问题,但也可以编写旁注。

标签: php image compare gd


【解决方案1】:

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

Face detection with PHP
Image Nudity Filter (Class)

【讨论】:

    【解决方案2】:

    大多数其他答案都涉及使用各种散列函数。这个问题明确地询问比较图像的内容,而不是比较文件。

    这意味着您最终必须真正了解图像的内容。在 PHP 中有两个常用的扩展,ImageMagick 和 GD。

    ImageMagick 通过 PHP ImageMagick 扩展提供了多种工具供您使用。

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

    最大的问题是该库的文档几乎不存在,因此需要进行大量的反复试验。 PHP 扩展是 ImageMagick 库的一个非常薄的包装器,因此可以在 ImageMagick 文档中找到 compareimages() 函数如何表现的详细信息。

    【讨论】:

    • 找不到文件。 - 如果您点击链接
    • 如果我们不依赖图书馆....那是怎么回事?
    • 不确定我是否理解您的问题,gumuruh?如果您不想依赖库,则必须自己编写算法来解析+处理图像。 ImageMagick 是开源的,所以如果你有很多时间(并且愿意牺牲效率),我想你可以编写一个 PHP-native 实现。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:
      $md5image1 = md5(file_get_contents($image1));
      $md5image2 = md5(file_get_contents($image2));
      if ($md5image1 == $md5image2) {
      
      }
      

      【讨论】:

      • 为什么不直接使用 md5_file()?
      • 这真的是一个文件比较。与其说是图像比较,问题是什么。
      • @Jason 为什么不只是 ($image1 == $image2)
      • 我不知道为什么,但是当我比较 2 个相同的图像时,md5 失败而 md5_file 正在工作
      • 如果你比较的是不同软件(甚至不同的 libpng 版本)生成的图像,那么同一个图像在磁盘上可能有不同的二进制表示,所以 MD5 比较会失败。
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        有人在 Stackoverflow thread 上提出了类似的问题,我开发了一些东西供自己使用。将其发布在此处,以便对其他人有所帮助。

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

        我写的比较全面blogpost on it as well

        【讨论】:

        • 这实际上是一个很棒的脚本。
        【解决方案7】:

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

        【讨论】:

        【解决方案8】:

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

        我担心时间,所以我包括了一些选项,例如:

        但是看到结果,如果您正在执行批量操作,也许最好的方法是硬编码选项以避免条件行的开销

        这是代码,带有一些测试和一个基准

        <?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.
        ?>
        

        【讨论】:

          猜你喜欢
          • 2022-12-15
          • 1970-01-01
          • 2016-10-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-15
          • 1970-01-01
          相关资源
          最近更新 更多