php - puede - reparar fotos dañadas que no se abren
¿Detecta eficientemente el archivo jpeg dañado? (8)
¿Hay una forma eficiente de detectar si un archivo jpeg está dañado?
Información de fondo:
soluciones necesita trabajar desde dentro de un script php
los archivos jpeg están en el disco
la verificación manual no es una opción (datos cargados por el usuario)
Sé que imagecreatefromjpeg(string $filename);
lo puede hacer. Pero es bastante lento al hacerlo.
¿Alguien sabe una solución más rápida / más eficiente?
Desde la línea de comandos, puede usar jpeginfo para averiguar si un archivo jpeg es correcto o no.
$ jpeginfo -c test.jpeg
test.jpeg 260 x 264 24bit JFIF N 15332 [OK]
Debería ser trivial llamar a jpeginfo desde php.
También puede intentar generar hash de archivo basado en MD5 y usarlo como suma de verificación para validar datos JPEG en varios pasos. Por ejemplo, después de leer el archivo, luego de la transferencia, etc.
Mi solución más simple (y más rápida):
function jpeg_file_is_complete($path) {
if (!is_resource($file = fopen($path, ''rb''))) {
return FALSE;
}
// check for the existence of the EOI segment header at the end of the file
if (0 !== fseek($file, -2, SEEK_END) || "/xFF/xD9" !== fread($file, 2)) {
fclose($file);
return FALSE;
}
fclose($file);
return TRUE;
}
function jpeg_file_is_corrupted($path) {
return !jpeg_file_is_complete($path);
}
Nota: Esto solo detecta una estructura de archivo dañada, pero NO detecta datos de imagen dañados.
Solución:
Encontré la herramienta perfecta para lo que necesitaba:
Busca de manera recursiva a través de un directorio y encuentra cualquier archivo JPEG dañado. Parece que puedes usar tantas CPU como quieras para hacerlo también.
Trabajó para mi.
Tengo otra solución con simplemente getimagesize ()
if(!getimagesize($image_url)) echo ''Image is corrupt or not readable'';
Por favor pruebalo
<?php
$img = $_GET[''img''];
$str_exec = ''jpeginfo -c /chroot/home/www/html/media/''.$img;
$result = exec($str_exec);
if(strpos($result, ''ERROR''))
{
echo ''ERROR'';
}
else
{
echo ''OK'';
}
?>
Una pequeña nota: ¿cómo obtener jpeginfo para Windows (64 bit)? No hay binarios win32 / win64 en github del autor, pero puede hacer esto:
1) toma jpeginfo.exe
de este archivo: https://github.com/MoserMichael/cstuff/raw/master/img-archive/img-archive.zip
2) capturar cygwin1.dll
de este archivo: ftp://mirror.internode.on.net/pub/cygwin/x86/release/cygwin64/cygwin64-2.6.0-1.tar.xz
jpeginfo --help
desde la línea de comandos si funciona: jpeginfo --help
. Si hay información, funciona bien.
Cómo probar la salida jpeginfo?
jpeginfo
devuelve 0 si el archivo está bien, pero devuelve 1, no solo cuando no lo es, sino también cuando encuentra algo que no comprende. Entonces genera un mensaje como este:
Warning: unknown JFIF revision number 2.01 1280 x 720 24bit JFIF N 122550 [WARNING]
En los archivos dañados, devuelve 1 y un mensaje como este:
1328 x 2048 24bit JFIF N 1310080 Premature end of JPEG file [WARNING]
Por lo tanto, es posible que desee probar el resultado real, no solo el código de retorno.
FYI - He usado el método anterior ( jpeg_file_is_complete
) para probar jpeg_file_is_complete
JPEG que sé que están corruptos (cuando los cargo en un navegador, por ejemplo, la parte inferior es gris, es decir, la imagen está "cortada"). De todos modos, cuando ejecuté la prueba anterior en esa imagen, NO la detecté como corrupta.
Hasta ahora, el uso de imagecreatefromjpeg()
funciona, pero no es muy rápido. Descubrí que el uso de jpeginfo
funciona para detectar este tipo de imágenes corruptas, y es MÁS RÁPIDO que imagecreatefromjpeg
(ejecuté un punto de referencia en mi PHP usando microtime()
).