【问题标题】:PHP: Determine Visually Corrupted Images (yet valid) downloaded via Curl with GD/ImagemagickPHP:使用 GD/Imagemagick 确定通过 Curl 下载的视觉损坏图像(但有效)
【发布时间】:2012-02-18 04:29:57
【问题描述】:

我正在使用 Curl via Proxies 通过我开发的刮刀下载图像。

不幸的是,它得到了看起来像这样的奇怪图像,最后一个完全空白:/

  • 当我通过 imagemagick(使用识别)测试图像时,它告诉我它们是有效的图像。
  • 当我再次通过 exif_imagetype() 和 imagecreatefromjpeg() 测试图像时,这两个函数都告诉我图像是有效的。

有没有人可以确定图像是否具有大部分灰度或完全空白/白色,而这些确实是损坏的图像?

我已经对这里的其他问题进行了很多检查,但我对其他解决方案的运气并不好。所以请小心暗示这是重复的。

谢谢


在了解了 imgcolorat 之后,我进行了搜索,偶然发现了一些代码。我想出了这个:

<?php

$file = dirname(__FILE__) . "/images/1.jpg";

$img = imagecreatefromjpeg($file);

$imagew = imagesx($img);
$imageh = imagesy($img);
$xy = array();

$last_height = $imageh - 5;

$foo = array();

$x = 0;
$y = 0;
for ($x = 0; $x <= $imagew; $x++) 
{
    for ($y = $last_height;$y <= $imageh; $y++ ) 
    {
        $rgb = @imagecolorat($img, $x, $y);

        $r = ($rgb >> 16) & 0xFF;
        $g = ($rgb >> 8) & 0xFF;
        $b = $rgb & 0xFF;

        if ($r != 0)
        {
            $foo[] = $r;
        }
    }
}

$bar = array_count_values($foo);

$gray = (isset($bar['127']) ? $bar['127'] : 0) + (isset($bar['128']) ? $bar['128'] : 0) + (isset($bar['129']) ? $bar['129'] : 0);
$total = count($foo);
$other = $total - $gray;

if ($gray > $other)
{
    echo "image corrupted \n";
}
else
{
    echo "image not corrupted \n";
}
?>

有人发现这有一些潜在的陷阱吗?我考虑获取图像的最后几行,然后将 r 127,128,129(灰色)的总数与其他颜色的总数进行比较。如果灰色大于其他颜色,则图像肯定已损坏。

欢迎发表意见! :)

【问题讨论】:

  • 嗯。如果所有这些函数都说它是一个有效的图像,它们可能只是检查头字节,而不是查看整个文件是否真的在那里。我希望有一个标头字节指定预期的,但我不确定是否存在这样的事情

标签: php imagemagick php-gd


【解决方案1】:

如果您使用-verbose 选项调用ImageMagick 的identify 命令,它将识别出更多损坏的图像。还有一个-regard-warnings 选项,它会将警告视为错误。对坏图像尝试这些,看看结果是否是非零错误代码。

【讨论】:

    【解决方案2】:

    我用这个。如果右下角 (5x5) 的大部分像素为灰色,则图像损坏。

        define('MIN_WIDTH',500);
        define('MIN_HEIGHT',200);
    
        function isGoodImage($fn){
            list($w,$h)=getimagesize($fn);
            if($w<MIN_WIDTH || $h<MIN_HEIGHT) return 0;
            $im=imagecreatefromstring(file_get_contents($fn));
            $grey=0;
            for($i=0;$i<5;++$i){
                for($j=0;$j<5;++$j){
                        $x=$w-5+$i;
                        $y=$h-5+$j;
                        list($r,$g,$b)=array_values(imagecolorsforindex($im,imagecolorat($im,$x,$y)));
                        if($r==$g && $g==$b && $b==128)
                            ++$grey;
                }
            }
            return $grey<12;
        }
    

    【讨论】:

      【解决方案3】:

      在寻找检查此类视觉损坏图像的方法时发现了此页面。这是一种使用bash解决问题的方法(无论如何,转换命令行可以很容易地适应php或python):

      convert INPUTFILEPATH -gravity SouthWest -crop 20%x1%   -format %c  -depth 8  histogram:info:- | sed '/^$/d'  | sort -V | head -n 1 | grep fractal | wc -l
      

      它在图片的西南角裁剪一个小方块,然后得到这张图片的直方图。如果直方图的主要颜色名称为“分形”而不是 rgb 颜色,则表示该区域已损坏,因此输出将为 10 否则。

      希望这会有所帮助!

      【讨论】:

      • 似乎有效。直方图中的“分形”实际上是什么意思?
      • Fractal 只是 #808080 的颜色名称。我知道这是旧的,但我们刚刚遇到了一个问题,即图像的底部实际上是有效的灰色。如果能够指定应该使用什么“默认”颜色而不是“分形”,那真是太好了,有什么想法吗?
      【解决方案4】:

      如果它返回的图像是有效文件,那么我建议运行两次抓取(即下载两次并检查它们是否相同)。

      另一种选择是检查图像的最后几个像素(即右下角),看看它们是否与灰色的颜色完全匹配。如果他们这样做,然后重新下载。 (显然,如果您下载的图像在那个角落实际上应该是灰色的,以那种确切的颜色......但如果您检查最后几个像素,它应该将这种可能性降低到可接受的水平)。

      【讨论】:

      • *第二种方法假设您的抓取工具实际上完全填充了整个图像,而不仅仅是部分阻塞,并为您提供部分文件。
      • 我完全赞成检查图像的最后几个像素,看看它是否是灰色的。我只是不知道该怎么做。如果您确实提出了解决方案,请检查提供的图片。
      • 非常感谢。我已经下载了 60,000 张需要检查的图像以及我设计的代码 sn-p。我现在已经检查了所有这些,并且没有损坏的图像。干杯!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多