简体   繁体   中英

DomPDF: Image not readable or empty

For some reason, DomPDF won't render an image included in the html that is being parsed:

PDF 图像丢失

However, the image is rendered on the page when it is returned as html:

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?

Following helped me like charm, at least localy, and even with

def("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

Thanks to this: lost in code

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.

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

Now (May 2018) the correct way is :

$options = new Options();
$options->set('isRemoteEnabled',true);      
$dompdf = new Dompdf( $options );

您可以使用 base64 编码的图像

<img src="{{'data:image/png;base64,' . base64_encode(file_get_contents(@$image))}}" alt="image" >

You don't really need isRemoteEnabled turned on, if all your images and what not are on the same server that executes the script.

Why it doesn't load your image

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.

Security note

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.

Usage note

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);

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.

None of the solutions here worked for me. Instead I just base64 encoded the image and then it worked. You can use this tool .

In path :

vendor/dino/dompdf-module/config/module.config.php

change settings

enable_remote' => false,

то true.

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 '';
        }
    }

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM