Creación de una matriz poblada por imágenes de un PDF usando PHP e ImageMagick
Frecuentes
Visto 2,582 equipos
2
Estoy tratando de escribir una rutina que tome un PDF enviado por un usuario, extraiga cada página como una imagen y luego complete una matriz con esas imágenes. Encontré varios ejemplos que agregan todas las páginas a una imagen, pero ninguno que hace lo que necesito.
Esto es lo que tengo, pero devuelve una matriz vacía:
function PdfToImg($pdf_in) {
$img_array = array();
$im = new imagick();
$im->readimageblob($pdf_in); // reading image from binary string
$num_pages = $im->getnumberimages();
$im->setimageformat("png");
for ($x =1;$x <= $num_pages; $x++) {
$img = $im->previousimage();
$img_array .= $img;
}
return $img_array;
}
Una de las advertencias aquí es que no puedo escribir estos archivos en el disco, debo usar cadenas/matrices. Revisé el manual de ImageMagick y no encontré nada sobre la salida de múltiples imágenes a una matriz, solo a una serie de archivos guardados en el disco.
ACTUALIZACIÓN: (06/13/2012) Encontré una manera de lograr lo que necesito, pero es fea, ineficiente y estoy seguro de que es lenta, pero no parecía haber otra manera.
function PdfToImg3($pdf_in) {
$img_array = array();
$im = new imagick();
$im->readimageblob($pdf_in);
$num_pages = $im->getnumberimages();
$i = 0;
for($x = 1;$x <= $num_pages; $x++) {
$im = new imagick();
$im->readimageblob($pdf_in);
$im->setiteratorindex($i);
$im->setimageformat('png');
$img_array[$x] = $im->getimageblob();
$im->destroy();
$i++;
}
$im->destroy();
return $img_array;
}
Produce una matriz denominada $img_array, con las páginas del PDF entrante que residen dentro de las claves de $img_array como cadenas de datos de imagen PNG.
DEBE haber una mejor manera, ¿por qué nextImage() no funciona? ¿Por qué no puedo usar setIteratorIndex sin reiniciar/(¿crear nuevos?) objetos imagick cada vez? Debo estar perdiendo algo, pero hay grandes agujeros en la documentación y Google, los foros de ImageMagick, ni StackOverflow saben nada de que esto se haya hecho con éxito.
PROBADO: Extremadamente lento, un PDF simple de 17 páginas tarda casi un minuto.
ACTUALIZACIÓN 2: (07/11/2012) Después de terminar el proyecto más grande en el que entró este bit de código, decidí volver a algunos puntos y mejorar el rendimiento. Esto es lo que se me ocurrió:
$img_array = array();
$im = new imagick();
$im->readimageblob($pdf_in);
$num_pages = $im->getnumberimages();
$im->destroy();
$i = 0;
for($x = 1;$x <= $num_pages; $x++) {
$im = new imagick();
$im->readimageblob($pdf_in);
$im->setResolution(300,300);
$im->setiteratorindex($i);
$im->setimageformat('png');
$img_array[$x] = $im->getimageblob();
$im->destroy();
$i++;
}
return $img_array;
Este cambio resultó en una conversión de PDF complejo de 4 páginas que pasó de 21 a 25 segundos a aproximadamente 2 a 3 segundos. Entiendo por qué algunos de los cambios ayudaron, no tan claro en los demás. Esperemos que alguien encuentre esto útil.
ACTUALIZACIÓN 3: descubrí por qué el rendimiento aumentó tanto, moviendo 'setResolution a debajo de 'readImageBlob' hace que se ignore la configuración de DPI, que por defecto es 72. En nota de esto, moví la declaración hacia atrás, la reduje a 150 y logré resultados similares pero aún mucho mejor rendimiento. Ver notas en php.net aquí.
1 Respuestas
2
Esta lectura y destrucción de blobs todo el tiempo probablemente nos está ralentizando mucho, de hecho, no los necesitamos en absoluto, el código pelado se ve así:
$img_array = array();
$im = new imagick();
$im->setResolution(150,150);
$im->readImageBlob($pdf_in);
$num_pages = $im->getNumberImages();
for($i = 0;$i < $num_pages; $i++)
{
$im->setIteratorIndex($i);
$im->setImageFormat('jpeg');
$img_array[$i] = $im->getImageBlob();
}
$im->destroy();
contestado el 09 de mayo de 13 a las 19:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas php arrays imagemagick imagick or haz tu propia pregunta.