2017-07-23 67 views
1

为了从节点生成PDF文件,我在Drupal 8上创建了模块,因为要求是这个PDF看起来和我想要在PNG中创建屏幕截图一样,并将其转换为PDF使用Imagick。使用PHP中的Imagick将PNG转换为PDF

一切顺利,直到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格式改变的实例吗?

回答

0

readImageBlob()从二进制字符串读取图像。在你的情况下,你需要readImage()谁从文件名读取图像。

此外,您将不得不使用setFormat()方法而不是setImageFormat()方法。

即:

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

希望它能帮助。