2017-07-23 3 views
1

J'ai créé module Drupal 8 afin de générer un fichier PDF à partir du nœud, car la demande est que ce PDF ressemble exactement à la page que je veux créer capture d'écran en PNG et pour le convertir en PDF en utilisant Imagick.Convertir PNG en PDF en utilisant Imagick en PHP

Tout va bien jusqu'à ce que Imagick, je reçois ceci:

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

Mais l'image est là et il est ok, je peux l'ouvrir sans aucun problème.

Voici mon code:

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

Suis-je manque quelque chose? Quelqu'un peut-il m'aider à résoudre ceci ou me donner un exemple de travail pour le format PNG au format PDF?

Répondre

0

readImageBlob() lit image à partir d'une chaîne binaire. Dans votre cas, vous avez besoin de readImage() qui lit l'image du nom de fichier. De plus, vous devrez utiliser la méthode setFormat() au lieu de la méthode setImageFormat().

à savoir:

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

Vous pouvez obtenir une liste des formats pris en charge avec $im->queryFormats().

La dernière étape consistera à passer la méthode getImage() à l'objet Response.

Je voudrais écrire quelque chose comme ça (non testé):

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

Hope it helps.