Creación de una matriz poblada por imágenes de un PDF usando PHP e ImageMagick

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í.

preguntado el 12 de junio de 12 a las 21:06

1 Respuestas

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 or haz tu propia pregunta.