在 PHP 中使用 Imagick 将 PNG 转换为 PDF
Convert PNG to PDF using Imagick in PHP
我在 Drupal 8 上创建了模块以便从节点生成 PDF 文件,因为请求是这个 PDF 看起来与我想在 PNG 中创建屏幕截图并使用 Imagick 将其转换为 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 格式更改的工作示例吗?
readImageBlob()
从二进制字符串中读取图像。在你的情况下,你需要 readImage()
who reads image from filename.
此外,您必须使用 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"'
)
);
}
}
希望对您有所帮助。
我在 Drupal 8 上创建了模块以便从节点生成 PDF 文件,因为请求是这个 PDF 看起来与我想在 PNG 中创建屏幕截图并使用 Imagick 将其转换为 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 格式更改的工作示例吗?
readImageBlob()
从二进制字符串中读取图像。在你的情况下,你需要 readImage()
who reads image from filename.
此外,您必须使用 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"'
)
);
}
}
希望对您有所帮助。