PHP: Определите визуально поврежденные изображения (но действительные), загруженные через Curl с помощью GD/Imagemagick


Я использую Curl через прокси-серверы для загрузки изображений с помощью скребка, который я разработал.

К сожалению, он получает странное изображение, похожее на это, и последнее полностью пустое:/

3/4 corrupteddog corruptedroom corruptedcompletely white

  • Когда я тестирую изображения с помощью imagemagick (используя identify), он сообщает мне, что они являются действительными изображениями.
  • Когда я снова тестирую изображения с помощью 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 (которые являются серыми) с общим количеством других цветов. Если серый цвет больше, чем другие цвета, то изображение, несомненно, повреждено.

Мнения приветствуются!:)

Author: PaulM, 2012-01-25

4 answers

Если возвращаемое изображение является допустимым файлом, то я бы рекомендовал выполнить очистку дважды (т. Е. загрузите его дважды и проверьте, совпадают ли они).

Другим вариантом было бы проверить последние несколько пикселей изображения (т.Е. Нижний правый угол), чтобы увидеть, точно ли они соответствуют этому серому цвету. Если они это сделают, то перезагрузите. (очевидно, что этот подход не работает, если вы загружаете изображение, которое на самом деле должно быть серым в этом углу, в этом точном цвете...но если вы проверьте несколько последних пикселей, это должно снизить вероятность этого до приемлемого уровня).

 1
Author: CasualT, 2012-01-24 22:23:59

Нашел эту страницу, когда искал способ проверить визуально поврежденные изображения, подобные этому. Вот способ решить проблему с помощью bash (в любом случае, командную строку convert можно легко адаптировать для 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, это означает, что эта зона повреждена, и поэтому вывод будет 1 и 0 в противном случае.

Надеюсь, это поможет!

 4
Author: TheFargue, 2013-10-11 14:58:02

Я использую этот. Если большинство пикселей в правом нижнем углу (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;
    }
 2
Author: 13DaGGeR, 2014-02-13 09:28:18

Команда ImageMagick identify идентифицирует гораздо больше поврежденных изображений, если вы вызовете ее с опцией -verbose. И еще есть опция -regard-warnings, которая позволит рассматривать предупреждения как ошибки. Попробуйте применить их к плохому изображению и посмотрите, является ли результат ненулевым кодом ошибки.

 0
Author: Korny, 2016-10-19 11:02:54