2012-01-24 24 views
5

Estoy usando Curl a través de Proxies para descargar imágenes con un raspador que he desarrollado.PHP: Determine las imágenes corruptas visualmente (aún válidas) descargadas a través de Curl con GD/Imagemagick

Por desgracia, se pone la extraña imagen que se parece a estos y la última es completamente en blanco:/

3/4 corrupted dog corrupted room corrupted completely white

  • Cuando pruebo las imágenes a través de ImageMagick (usando identificar) me dice que son imágenes válidas.
  • Cuando pruebo las imágenes a través de exif_imagetype() y imagecreatefromjpeg() nuevamente, ambas funciones me dicen que las imágenes son válidas.

¿Alguien tiene una manera de determinar si la imagen tiene una mayoría de grisáceo o está completamente en blanco/blanco y estas son de hecho imágenes dañadas?

He realizado muchas comprobaciones con otras preguntas aquí, pero no he tenido mucha suerte con otras soluciones. Por favor, tenga cuidado al sugerir que este es un duplicado.

Gracias


Después de conocer acerca imgcolorat, hice una búsqueda y topé con algo de código. Se me ocurrió esto:

<?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"; 
} 
?> 

¿Alguien ve algunas trampas potenciales con esto? Pensé en obtener las últimas filas de la imagen y luego comparar el total de r 127,128,129 (que son grises) con el total de otros colores. Si el gris es mayor que los otros colores, la imagen seguramente se corrompe.

¡Bienvenido! :)

+0

Hmm. Si todas esas funciones dicen que es una imagen válida, probablemente solo verifiquen los bytes del encabezado, pero no miran si todo el archivo realmente está * allí *. Esperaría que haya un byte de encabezado que especifique el esperado con, pero no sé con certeza si existe tal cosa –

Respuesta

1

Si la imagen que está devolviendo es un archivo válido, entonces recomendaría ejecutar el raspado dos veces (es decir, descargarlo dos veces y verificar si son iguales).

Otra opción sería comprobar los últimos píxeles de la imagen (es decir, la esquina inferior derecha) para ver si coinciden exactamente con ese color de gris. Si lo hacen, luego volver a descargar. (Obviamente, este enfoque falla si descarga una imagen que se supone que es gris en esa esquina, en ese color exacto ... pero si marca varios de los últimos píxeles, debería reducir la probabilidad de que alcance un nivel aceptable).

+0

* Este segundo enfoque supone que su herramienta de raspado está llenando realmente toda la imagen y no solo asfixiando la pieza a través de, y le da un archivo parcial. – CasualT

+0

Estoy a favor de verificar los últimos píxeles de la imagen para ver si es gris. Simplemente no sé cómo hacer esto. Si encuentra una solución, consulte las imágenes proporcionadas. – PaulM

+0

esto debería hacer el truco: http://php.net/manual/en/function.imagecolorat.php – CasualT

4

encontró esta página cuando buscaba una manera de comprobar las imágenes visualmente dañadas como esta. Aquí es una manera de resolver el problema con bash (de todos modos, la línea de comando de conversión se puede adaptar fácilmente para PHP o 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 

Se recorta una pequeña plaza en la esquina suroeste de la imagen, a continuación, obtiene la histograma de esta imagen. Si el color principal del histograma tiene el nombre "fractal" en lugar de un color rgb, significa que esta zona está dañada y, por lo demás, la salida será 1 y 0.

Espero que esto ayude!

+0

Parece que funciona. ¿Qué significa 'fractal' en realidad en el histograma? – Frans

+0

Fractal es simplemente el nombre del color para # 808080. Sé que esto es viejo, pero acabamos de encontrar un problema donde la parte inferior de la imagen es realmente gris. Sería realmente agradable poder especificar qué color "predeterminado" debería existir en lugar de "fractal", ¿alguna idea? –

2

Utilizo este. Si la mayoría de los píxeles en la esquina inferior derecha (5x5) son grises, la imagen se rompe.

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; 
    } 
0

comandos de ImageMagick identify identificará imágenes mucho más corruptos si se llama con la opción -verbose. Y también hay una opción -regard-warnings, que lo hará tratar las advertencias como errores. Pruebe esto con una mala imagen y vea si el resultado es un código de error distinto de cero.

Cuestiones relacionadas