Преобразование PNG в PDF с помощью Imagick в PHP

Я создал модуль на Drupal 8, чтобы сгенерировать PDF-файл из узла, поскольку требуется, чтобы этот PDF-файл выглядел точно так же, как страница, которую я хочу создать в формате PNG, и преобразовать ее в PDF с помощью Imagick.

Все идет нормально, пока Imagick, я получаю это:

ImagickException: Zero size image string passed in Imagick->readimageblob() 

Но изображение есть, и все в порядке, я могу открыть его без проблем.

Вот мой код:

<?php
/**
 * @file
 * MyControllerBase
 */

namespace Drupal\my_pdf\Controller;

use Drupal\node\Entity\Node;
use Knp\Snappy\Image;
use Symfony\Component\HttpFoundation\Response;
use Drupal\Core\Controller\ControllerBase;

class MyPdfController extends ControllerBase {

  /**
   * @return \Symfony\Component\HttpFoundation\Response
   */
  public function createPdf($nodeid) {

    $node = Node::load($nodeid);
    $url = \Drupal::request()->getSchemeAndHttpHost() . $node->url();
    $module_path = drupal_get_path('module', 'verifone_pdf');
    $filename = 'node-id-' . $nodeid . '.png';

    $snappy = new Image('xvfb-run /usr/bin/wkhtmltoimage');
    $snappy->setOption('no-stop-slow-scripts', TRUE);
    $snappy->setOption('javascript-delay', 5000);
    $snappy->setOption('images', TRUE);
    $snappy->setOption('enable-smart-width', TRUE);
    $snappy->setOption('user-style-sheet', $module_path . '/css/style.css');
    $snappy->setOption('width', '1920');
    $snappy->setDefaultExtension('png');

    if(!file_exists("/tmp/$filename")) {
      $snappy->generate($url, "/tmp/$filename");
    }

    $image = imagecreatefrompng("/tmp/$filename");
    $im = new \Imagick();

    ob_start();
    imagepng($image);
    $image_data = ob_get_contents();
    ob_end_clean();

    // Get image source data
    $im->readimageblob($image_data);

    $im->setImageFormat('pdf');

    return new Response(
      $im,
      200,
      array(
        'Content-Type' => 'application/pdf',
        'Content-Disposition' => 'attachment; filename="page-' . $nodeid . '.pdf"'
      )
    );
  }
}

Я что-то упускаю? Может ли кто-нибудь помочь мне решить эту проблему или дать мне рабочий пример для изменения формата PNG в PDF?


person mixerowsky    schedule 23.07.2017    source источник


Ответы (1)


readImageBlob() читает изображение из двоичной строки. В вашем случае вам нужен readImage(), который читает изображение из имени файла.

Кроме того, вам придется использовать метод setFormat() вместо метода setImageFormat() .

i.e. :

$im = new \Imagick();
$im->readImage("/tmp/{$filename}");
$im->setFormat('pdf');

Вы можете получить список поддерживаемых форматов с помощью $im->queryFormats().

Последним шагом будет передача метода getImage() объекту Response.

Я бы написал что-то вроде этого (не проверено):

<?php
/**
 * @file
 * MyControllerBase
 */

namespace Drupal\my_pdf\Controller;

use Drupal\node\Entity\Node;
use Knp\Snappy\Image;
use Symfony\Component\HttpFoundation\Response;
use Drupal\Core\Controller\ControllerBase;

class MyPdfController extends ControllerBase
{
    /**
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function createPdf($nodeid)
    {
        $node = Node::load($nodeid);
        $url = \Drupal::request()->getSchemeAndHttpHost() . $node->url();
        $module_path = drupal_get_path('module', 'verifone_pdf');
        $filename = 'node-id-' . $nodeid . '.png';

        $snappy = new Image('xvfb-run /usr/bin/wkhtmltoimage');
        $snappy->setOption('no-stop-slow-scripts', TRUE);
        $snappy->setOption('javascript-delay', 5000);
        $snappy->setOption('images', TRUE);
        $snappy->setOption('enable-smart-width', TRUE);
        $snappy->setOption('user-style-sheet', $module_path . '/css/style.css');
        $snappy->setOption('width', '1920');
        $snappy->setDefaultExtension('png');

        if(!file_exists("/tmp/$filename")) {
            $snappy->generate($url, "/tmp/{$filename}");
        }

        $im = new \Imagick();    
        $im->readImage("/tmp/{$filename}");
        $im->setFormat('pdf');

        return new Response(
            $im->getImage(),
            200,
            array(
                'Content-Type' => 'application/pdf',
                'Content-Disposition' => 'attachment; filename="page-' . $nodeid . '.pdf"'
            )
        );
    }
}

Надеюсь, поможет.

person JazZ    schedule 19.10.2017