Reputation:
For some reason, DomPDF won't render an image included in the html that is being parsed:
However, the image is rendered on the page when it is returned as html:
I've looked at these issues and have make sure that DOMPDF_ENABLE_REMOTE is set to true and verified file permissions:
dompdf image not real image not readable or empty
Image error in DOMPDF for ZF2
Are there any other things that I should be checking for?
Upvotes: 38
Views: 138155
Reputation: 309
I had this problem when loading local images and figured out that
$dompdf->getOptions()->setChroot($path_to_images);
was not enough, I additionally had to set
chdir($path_to_images);
Upvotes: 1
Reputation: 610
Following helped me like charm, at least localy, and even with
define("DOMPDF_ENABLE_REMOTE", false);
The solution is to change the image SRC to the absolute path on the server, like this:
<img src="/var/www/domain/images/myimage.jpg" />
All of the following worked for me:
<img src="<?php echo $_SERVER["DOCUMENT_ROOT"].'/placeholder.jpg';?>"/>
<img src="<?php echo $_SERVER["DOCUMENT_ROOT"].'\placeholder.jpg';?>"/>
<img src="<?php echo $_SERVER["DOCUMENT_ROOT"].'./placeholder.jpg';?>"/>
$_SERVER["DOCUMENT_ROOT"] is C:/wamp/www/ZendSkeletonApplication/public
Upvotes: 55
Reputation: 1853
You don't really need isRemoteEnabled
turned on, if all your images and what not are on the same server that executes the script.
DomPdf protects you from being attacked through it. As per documentation the following won't work:
$dompdf = new Dompdf();
$dompdf->getOptions()->getChroot(); // something like 'C:\\laragon\\www\\your-local-website\\vendor\\dompdf\\dompdf'
$html = <<<HTML
<!DOCTYPE html>
<html lang="en">
<body>
<img src="C:\\laragon\\www\\your-local-website\\public\\img\\logo.png">
</body>
</html>
HTML;
$dompdf->loadHtml($html);
You should change CHROOT to your desired absolute path with
$dompdf->getOptions()->setChroot("C:\\laragon\\www\\your-local-website\\public");
and then you can insert any <img>
with src
from within (can be nested) that /public
folder into HTML.
It seems like an easy win to just set Chroot to your app root folder, but don't. It opens up a nasty gate, one you want to keep shut. Supposedly there are no critical scripts in /public
, only images, public documents, routing etc.
Note that I used a different directory separator than the one being used in documentation. I believe the best practice would be to do something in lines of:
define('DS', DIRECTORY_SEPARATOR);
$public = ABSPATH . DS . 'public'; // ABSPATH is defined to be __DIR__ in root folder of your app
$image = $public . DS . 'logo' . DS . 'logo-md.png';
/* Optional */
$saveLocation = ABSPATH . DS . '..' . DS . 'private' . DS . 'invoices'; // Note that save location doesn't have to be in '/public' (or even in 'www')
$html = <<<HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style type="text/css">
* {
font-family: DejaVu Sans !important;
}
@page {
margin: 0;
padding: 0;
}
html, body {
margin: 0;
min-height: 100%;
padding: 0;
}
</style>
</head>
<body>
<img src="{$image}">
</body>
</html>
HTML;
$dompdf = new Dompdf();
$dompdf->getOptions()->setChroot($public);
$domPdf->loadHtml($html, 'UTF-8');
$domPdf->setPaper('A4', 'portrait');
$domPdf->render();
/* either */
$domPdf->stream($filename); // filename is optional
/* or */
$outputString = $domPdf->output();
$pdfFile = fopen($saveLocation, 'w');
fwrite($pdfFile, $outputString);
fclose($pdfFile);
Upvotes: 9
Reputation: 2775
You can use base64 encoded image
<img src="{{'data:image/png;base64,' . base64_encode(file_get_contents(@$image))}}" alt="image" >
Upvotes: 13
Reputation: 623
For our use case we had to convert all the images on the page to base64 since the pdf should be usable offline. Our code lives inside a controller class but you can modify that to your needs.
Here's the code:
/**
* Convert images to Base64 so it's included in the PDF.
*
* @param $html Full html render of the page.
*/
public function convertReportImagesToURI($html): string
{
$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML($html);
$tags = $doc->getElementsByTagName('img');
$imgArr = array();
// Iterate over all image tags.
foreach ($tags as $tag) {
// Get the src attribute.
$imgSrc = $tag->getAttribute('src');
// Convert to base64.
$base64src = self::getImageDataURI($imgSrc);
$tag->setAttribute('src', $base64src);
}
return $doc->saveHTML();
}
/**
* This does the actual encoding.
*/
public static function getImageDataURI($image, $mime = ''): string
{
// Director::absoluteURL('/') gets the base url of the site.
// We had to remove the leading slash of the image hence the use of substr.
// If your images have absolute urls you will need to modify this.
$imageLocation = Director::absoluteURL('/') . substr($image, 1);
// Get the image location. remove leading slash on image url.
return 'data:' . self::get_image_mime_type($imageLocation) . ';base64,' . base64_encode(file_get_contents($imageLocation));
}
/**
* https://stackoverflow.com/a/45054843
* @param $image_path
* @return string
*/
public static function get_image_mime_type($image_path): string
{
$mimes = array(
IMAGETYPE_GIF => "image/gif",
IMAGETYPE_JPEG => "image/jpg",
IMAGETYPE_PNG => "image/png",
IMAGETYPE_SWF => "image/swf",
IMAGETYPE_PSD => "image/psd",
IMAGETYPE_BMP => "image/bmp",
IMAGETYPE_TIFF_II => "image/tiff",
IMAGETYPE_TIFF_MM => "image/tiff",
IMAGETYPE_JPC => "image/jpc",
IMAGETYPE_JP2 => "image/jp2",
IMAGETYPE_JPX => "image/jpx",
IMAGETYPE_JB2 => "image/jb2",
IMAGETYPE_SWC => "image/swc",
IMAGETYPE_IFF => "image/iff",
IMAGETYPE_WBMP => "image/wbmp",
IMAGETYPE_XBM => "image/xbm",
IMAGETYPE_ICO => "image/ico");
if (($image_type = exif_imagetype($image_path))
&& (array_key_exists($image_type, $mimes))) {
return $mimes[$image_type];
} else {
return '';
}
}
Upvotes: 1
Reputation: 281
Now (May 2018) the correct way is :
$options = new Options();
$options->set('isRemoteEnabled',true);
$dompdf = new Dompdf( $options );
Upvotes: 13
Reputation: 165
I solve this problem by using external CSS's full path. This one worked on my linux ubuntu server :
<link href="{{ public_path('css/style.css') }}" />
<img src="{{ public_path('images/image.jpg') }}" />
and work on image.
Upvotes: 4
Reputation: 767
As there was another answer that suggests enabling the remote option in module.config.php
and I can't yet add comments, I thought it would be best to answer that this file does not exist in newer versions of DomPDF.
If you need to include remotely stored images in a newer version you have to pass it as an option to the constructor:
$dompdf = new Dompdf(array('enable_remote' => true));
This fixed the issue I had.
Upvotes: 34
Reputation: 1212
None of the solutions here worked for me. Instead I just base64 encoded the image and then it worked. You can use this tool.
Upvotes: 2
Reputation: 25
In path :
vendor/dino/dompdf-module/config/module.config.php
change settings
enable_remote' => false,
то true.
Upvotes: -1
Reputation: 501
Ok I had the same problem with image using :
<img id="logo" src="/images/flags/fr.png" width="50" alt="Logo">
But if I add a . before /images, without changing anything in dompdf_config.custom.inc, it works
<img id="logo" src="./images/flags/fr.png" width="50" alt="Logo">
Hope it helps
Upvotes: 15