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

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

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

3/4 поврежденособака повреждена комната поврежденаполностью белый

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

Приветствуются мнения! :)


person PaulM    schedule 24.01.2012    source источник
comment
Хм. Если все эти функции говорят, что это правильное изображение, они, вероятно, просто проверяют байты заголовка, но не смотрят, действительно ли здесь находится весь файл. Я бы ожидал, что будет байт заголовка, который указывает ожидаемое значение with, но я точно не знаю, существует ли такая вещь.   -  person Pekka    schedule 25.01.2012


Ответы (4)


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

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

person CasualT    schedule 24.01.2012
comment
* Этот второй подход предполагает, что ваш инструмент очистки на самом деле полностью заполняет все изображение, а не просто забивается наполовину и дает вам частичный файл. - person CasualT; 25.01.2012
comment
Я полностью за проверку последних нескольких пикселей изображения, чтобы увидеть, является ли оно серым. Я просто не знаю, как это сделать. Если вы найдете решение, сверьтесь с предоставленными изображениями. - person PaulM; 25.01.2012
comment
Большое спасибо за это. Я уже загрузил 60 000 изображений, которые нужно было проверить, и фрагмент кода, который я разработал. Теперь я проверил их все, и у меня нет битых изображений. Ваше здоровье! - person PaulM; 25.01.2012

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

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

person TheFargue    schedule 11.10.2013
comment
Кажется, работает. Что на самом деле означает «фрактал» на гистограмме? - person Frans; 24.04.2014
comment
Fractal — это просто название цвета #808080. Я знаю, что это старо, но мы только что столкнулись с проблемой, когда нижняя часть изображения действительно серая. Было бы очень хорошо иметь возможность указать, какой цвет по умолчанию должен быть там вместо фрактала, есть идеи? - person Stefan Wallin; 12.10.2016

Я использую этот. Если большая часть пикселей в правом нижнем углу (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;
    }
person 13DaGGeR    schedule 13.02.2014

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

person Korny    schedule 19.10.2016