barryvdh / laravel-dompdf

A DOMPDF Wrapper for Laravel
MIT License
6.71k stars 967 forks source link

Image not found or type unknown #303

Closed karlpatrickespiritu closed 2 years ago

karlpatrickespiritu commented 7 years ago

After updating the version to 0.7.0. The images (.png) are broken ("Image not found or type unknown").

imgnotfoumd

aodzylp commented 7 years ago

You need to add 'isRemoteEnabled' => true

Sample return PDF::setOptions(['isHtml5ParserEnabled' => true, 'isRemoteEnabled' => true])->loadView('reports.invoiceSell')->stream();

kirejko commented 7 years ago

@aodzylp It doesn't help, form me :disappointed:

noriega9807 commented 7 years ago

this worked for me: <img src="http://www.domain.com/path/to/image/image.png" />

Padmore51 commented 7 years ago

I get the same message when i print an image to pdf using laravel. Can you show a sample code of how to print an image to pdf.

sonamsingh28 commented 7 years ago

Enabling remote by setting options helped me fix this. ... $html = ''; $options = new Options(); $options->setIsRemoteEnabled(true); $dompdf = new Dompdf($options); $dompdf->loadHtml($html); $dompdf->output(); ...

raheemmiyasin commented 7 years ago

I solved it after changed to this: <img src="{{ base_path() }}/location/to/image/image.png" />

rafaelxavierborges commented 6 years ago

@noriega9807 is right. I used <img src="{{ url('/images/image.png') }}"> and it worked fine.

cuonghuynh commented 6 years ago

Seems that it does not work in the local domain. it worked fine in the public domain.

amadeann commented 6 years ago

I think it doesn't work when you customize options in any way.

laravel-dompdf defines a set of default options in config/dompdf.php. Whenever you customize these options either through setOptions method or a custom dompdf.php config file, all the defaults are ignored. Most likely some of the defaults are responsible for proper handling of images.

If this is true, then the issue can be solved by changing the behavior of the library to append-merge new options to the defaults.

amadeann commented 6 years ago

Added a PR fixing this.

kduszczy commented 6 years ago

If you still have problem with it. It might be due to something with ssl certificate, I just install one and the images stop showing. To fix it: $contxt = stream_context_create([ 'ssl' => [ 'verify_peer' => FALSE, 'verify_peer_name' => FALSE, 'allow_self_signed'=> TRUE ] ]); $pdf = PDF::setOptions(['isHtml5ParserEnabled' => true, 'isRemoteEnabled' => true]); $pdf->getDomPDF()->setHttpContext($contxt);

Santoshge-Reddy commented 6 years ago

Got The issue if there are spaces in the image name or URL's

So replace the image-name with %20 it will be solved

$image = str_replace(' ', '%20', $items->image);

SatishDanda commented 6 years ago

run it on htdocs. don't run using composer php artisan serve and give currect path url("/public/foldername/image.png").

ComputerGuruInTraining commented 6 years ago

I experience the problem intermittently. Some images render perfectly, some do not. And the ones that do will then not work in a few days time and the ones that don't will work.

I'm pretty certain I have narrowed down the problem. The images use a Shared Access Signature and the signature component of the SAS can include + signs (urlencoded to %2B). Every time an image doesn't render, I have found the signature has included a %2B which must be being converted to either a + or a space before accessing the img src url.

A solution would be very much appreciated.

truffolone commented 6 years ago

Solved with the allow remote. Fun fact is that some images from remote were still rendering correctly due to the pagespeed mod on apache2 which was caching the data. I narrowed down the issue after disabling all my cache mods.

I also was on an older version of dompdf (really old project and no time to refractor)

josesotomayor commented 6 years ago

Solution: Convert the image to base64

<img src=""data:image/png;base64, iVBORw0....." />

KobiMontague commented 6 years ago

'isRemoteEnabled' => true

Worked for me..thanks aodzylp

juancarlosestradanieto commented 6 years ago

I used @josesotomayor suggest. I created a custom class with the method that gets the base64.

`<?php namespace App\Custom;

class Archivos { public static function imagenABase64($ruta_relativa_al_public) { $path = $ruta_relativa_al_public; $type = pathinfo($path, PATHINFO_EXTENSION); $data = \File::get($path);

    $base64 = "";
    if ($type == "svg") {
        $base64 = "data:image/svg+xml;base64,".base64_encode($data);
    } else {
        $base64 = "data:image/". $type .";base64,".base64_encode($data);
    }
    return $base64;
}

}`

Then in the view i did this.

@php use App\Custom\Archivos; @endphp <img src="{{Archivos::imagenABase64('assets/img/logo_empresa_contrato.jpg')}}" width="200px" >

edomeru commented 6 years ago

`I've been having this problem for 3 days now, cant show image on pdf(used dompdf),i just wanna fetch the image locally using XAMPP on MAC, the image (goku.jpg) is located inside htdocs/images folder, already set the options, i guess the problem is with the path on src, tried everypath but still doesnt show, tried everything online but nothing seems to work.please help

2018-10-04 11 00 15

`<?php

require("config.inc.php"); // Include autoloader require_once 'dompdf/autoload.inc.php'; // $_dompdf_show_warnings = true; // $_dompdf_warnings = [];

use Dompdf\Dompdf; use Dompdf\Options; //if posted data is not empty $options = new Options(); $options->set('defaultFont', 'Courier'); $options->set('isRemoteEnabled', TRUE); $options->set('debugKeepTemp', TRUE); $options->set('isHtml5ParserEnabled', TRUE); $options->set('chroot', '/'); $options->setIsRemoteEnabled(true);

$dompdf = new Dompdf($options); $dompdf->set_option('isRemoteEnabled', TRUE);

$auth = base64_encode("username:password");

$context = stream_context_create(array( 'ssl' => array( 'verify_peer' => FALSE, 'verify_peer_name' => FALSE, 'allow_self_signed'=> TRUE ), 'http' => array( 'header' => "Authorization: Basic $auth" ) ));

$dompdf->setHttpContext($context);

$agent = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"; ini_set('user_agent', $agent);

if (isset($_GET['firstName'])){

$fileName = "https://i.ytimg.com/vi/1z3MA54hRW4/maxresdefault.jpg";

$root ='file:///kabushikikaishahaimessodo'. $_SERVER["DOCUMENT_ROOT"];
//$root = realpath(__DIR__);
$tempDir = $root.'/images/'; 

$fileName = 'goku.jpg'; $pngAbsoluteFilePath = $tempDir.$fileName;

$output = "

";

$fnme = $_GET['firstName'];

$query = " SELECT primarykey, firstName, lastName, address, contactNumber FROM booking WHERE firstName = :firstName ORDER BY primarykey DESC LIMIT 1 ";

$query_params = array( ':firstName' => $_GET['firstName'] );

//execute query try { $stmt = $db->prepare($query); $result = $stmt->execute($query_params); } catch (PDOException $ex) { $response["success"] = 0; $response["message"] = "Database Error!"; die(json_encode($response)); }

// Finally, we can retrieve all of the found rows into an array using fetchAll $rows = $stmt->fetchAll();

if ($rows) { $response["success"] = 1; $response["message"] = "User exist!"; $response["users"] = array();

foreach ($rows as $row) {
    $users             = array();
    $output .='<tr>
                     <th>'.$row['firstName'].' '.$row['lastName'].'  </th>
                     <th>'.$row['address'].'</th>
                     <th>'.$row['contactNumber'].'</th>
                     <th>'.$row['primarykey'].'</th>
                </tr>';

}
 $output .='</table><br/><br/>';

$output .= "

";

$dompdf->loadHtml($output); $dompdf->setPaper('A4','portrait'); $dompdf->render(); $dompdf->stream("spl",array("Attachment" => 0));

} else { $response["success"] = 0; $response["message"] = "No Users!"; die(json_encode($response)); }

}

?>`

josesotomayor commented 5 years ago

Solution: Convert to base 64 the image:

Example:

<'img' src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUA AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO 9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Example" />

ACvijic commented 5 years ago

Base 64 conversion is not a good solution for when images are dynamic. In that case you'd have to store them encoded somewhere or encode on the fly.. :disappointed:

ACvijic commented 5 years ago

What solved it for me was using public_path('path/to/image.png').

jorgeorisan commented 5 years ago

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

mahmuddin commented 5 years ago

@ACvijic Thanks, it's very simple way..

CalvinGrain commented 5 years ago

One way is to add domain to hosts file pointing to localhost

renbooo commented 5 years ago

public_path('path/to/image.png') work for me, thanks @ACvijic

userlond commented 5 years ago

It works for me this way (PHP5.6, DomPdf 0.8 standalone no-framework version)

<?php
// set some options
$options = [];
// ....
$pdf = new \Dompdf\Dompdf($options);
// set base url for the relative links,
// it's document root from environment variable in my case 
$pdf->setBasePath($_SERVER['DOCUMENT_ROOT']);

Next I place my image into $_SERVER['DOCUMENT_ROOT'] . '/files/img.png'

And my html template is

<html>
  <head>
    <title>Example</title>
  </head>
  <body>
    <img src="files/img.png">
  </body>
</html>
Gkiokan commented 5 years ago

It can be done though base_path() also:

{{ base_path() . '/storage/app/public/images/logo.png' }}

rekcX commented 5 years ago

I had the same issue and applied the solutions above. Still no luck until I figured out that the problem might be due to the use of htaccess. My site is protected by user password auth, which might have prohibited dompdf to access the image files. The base64 encoding might be a workaround for that, but increases workload.

Finally I could solve the issue by adding the line: Require local to my .htaccess file and now it works like a charm.

My .htacces file looks like this:


AuthType      Basic
AuthName      "Alpha-Access"
AuthUserFile  [...]
Require user demo, admin
Require local
Require valid-user
bogdanpatrasescu commented 4 years ago

'isRemoteEnabled' => true

Worked for me..thanks aodzylp

where can i add this option? in which file? Thanks!

daanlo commented 4 years ago

This won't solve the underlying problem, but turning the png file into a jpg file did the trick for me.

For my very specific use case that was the quickest solution.

aqeelnuces commented 4 years ago

its not working for me. i have tried .jpg file. i have tried 'isRemoteEnabled' => true but still keep giving me error

iamnotstatic commented 4 years ago

Solved it by setting the options PDF::setOptions(['isHtml5ParserEnabled' => true, 'isRemoteEnabled' => true])->loadView('models.receipt', ['receipt' => $receipt] )->setPaper('a5', 'portrait');

pmochine commented 4 years ago

Out of the blue I got this error as well. public_path('path/to/image.png') works before that I used asset('path/to/image.png')

Dilshan97 commented 4 years ago

public_path('path/to/image.png') work for me Thanks

phildkevin commented 4 years ago

In my case. I need to add canvas(graph) to my pdf. what i did is convert the canvas to base64 image, but It does not render the converted image on downloaded pdf. How can i render a non locally stored base64 image?

sayhicoelho commented 4 years ago

What solved it for me was using public_path('path/to/image.png').

solved the issue! thanks!

tomaslucena commented 4 years ago

Just did a clean installation on my laravel project... Have tried all the solutions above and nothing worked so far :(

reinaldoagf commented 4 years ago
andrebhas commented 4 years ago

I used @josesotomayor suggest. I created a custom class with the method that gets the base64.

`<?php namespace App\Custom;

class Archivos { public static function imagenABase64($ruta_relativa_al_public) { $path = $ruta_relativa_al_public; $type = pathinfo($path, PATHINFO_EXTENSION); $data = \File::get($path);

  $base64 = "";
  if ($type == "svg") {
      $base64 = "data:image/svg+xml;base64,".base64_encode($data);
  } else {
      $base64 = "data:image/". $type .";base64,".base64_encode($data);
  }
  return $base64;
}

}`

Then in the view i did this.

@php use App\Custom\Archivos; @endphp <img src="{{Archivos::imagenABase64('assets/img/logo_empresa_contrato.jpg')}}" width="200px" >

this worked for me, thanks @josesotomayor

midoridge commented 4 years ago

If your environment is using dompdf/dompdf version 0.8.6, this version is strict checking local path more than previous version.

This version checks "open_basedir" in php.ini via realpath method. So, you need to set "chroot" option.

For example,

document root is "/var/www/html"

php.ini

open_basedir = /var/www/:/var/lib/php/session/:/var/lib/php/wsdlcache/:/tmp/

example.blade.php

<img src="{{ public_path('images/example.png') }}">

caller as PdfController

use Barryvdh\DomPDF\Facade as PDF;

class PdfController
    public function pdf()
    {
        return PDF::loadView('example')
                  ->setPaper('a4')
                  ->setOptions([
                      'tempDir' => public_path(),
                      'chroot'  => '/var/www',
                  ]);
    }

If public_path() is "/var/www/html", you can also write the following

use Barryvdh\DomPDF\Facade as PDF;

class PdfController
    public function pdf()
    {
        return PDF::loadView('example')
                  ->setPaper('a4')
                  ->setOptions([
                      'tempDir' => public_path(),
                      'chroot'  => public_path(),
                  ]);
    }
nix1128 commented 4 years ago

I have set the options like

    'tempDir' => public_path(),
    'chroot'  => public_path('/path/where/images/are'),
    ]);

and have acess the image like

<img src="{{ public_path('/path/where/images/are/'.$foo->field) }}">

And it worked for me.

tripexito commented 3 years ago

Hi, I am having issues to download pdf file generated with png images, in chrome download dialog shows as .html instead of .pdf

image

image

I've been trying using images as base64 and its working the pdf file download in chrome but the images does not showing on pdf file downloaded. In Firefox Pdf Viewer there's no issues. Please tell how can I solve. Thanks.

marouane44 commented 3 years ago

I solved it after changed to this:

require_once 'dompdf/autoload.inc.php'; use Dompdf\Dompdf;

use Dompdf\Options; <----------------------------------------------------------------------------------------------------------->

this worked for me: <----------------------------------------------------------------------------------------------------------->

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

$pdf = new Dompdf($options); $contxt = stream_context_create([ 'ssl' => [ 'verify_peer' => FALSE, 'verify_peer_name' => FALSE, 'allow_self_signed'=> TRUE ] ]); $pdf->setHttpContext($contxt);

$file_name = 'Invoice-'.$row["order_no"].'.pdf'; $pdf->loadHtml(utf8_decode($output)); $pdf->render(); $pdf->stream($file_name, array("Attachment" => false));

KristianI commented 3 years ago

You have to ask yourself, is the PDF package (that runs on the backend) able to access the image on the URL when calling from the backend. (I know it sounds stupid obvious).

I was running this from inside a docker container. The image I was trying to fetch was using the URL specified in the APP_URL configuration, that worked from the outside world, as that domain was mapped in my /etc/hosts file on my development machine.

The hostname was not mapped inside the container though.

Temporarily hardcoding the domain in the image URL to "localhost" confirmed, that it indeed was the case.

In my case updating the /etc/hosts inside the docker container solved it.

Are you using custom port numbers for your docker containers, you have another problem.

lebroncho commented 3 years ago

public_path('path/to/image.png') Hello u use that as src like this <img src="public_path('path/to/image.png')" alt="Image">

munchy5132 commented 3 years ago

I think it doesn't work when you customize options in any way.

laravel-dompdf defines a set of default options in config/dompdf.php. Whenever you customize these options either through setOptions method or a custom dompdf.php config file, all the defaults are ignored. Most likely some of the defaults are responsible for proper handling of images.

If this is true, then the issue can be solved by changing the behavior of the library to append-merge new options to the defaults.

For me this worked

jhonatasgaragnani commented 3 years ago

Pessoal, Solucionei o problema passando a url da imagem assim no Laravel: "{{ env('APP_URL') }}/logo/logo.png"

gutoholiveira commented 3 years ago

Hello guys. for me this code works:

IN CONTROLLER:

public function report2()
    {
        $html = view('your_view');
        $options = new Options();
        $options->set('isRemoteEnabled', true);
        $options->set('chroot', realpath(base_path()));
        $options->set('enable_font_subsetting', false);
        $options->set('pdf_backend', 'CPDF');
        $options->set('default_media_type', 'screen');
        $dompdf = new Dompdf($options);
        $dompdf->loadHtml($html);
        $dompdf->render();
        $this->setEncryption($dompdf);
        $dompdf->stream('name_file');
    }

    public function setEncryption($dompdf)
    {
        $dompdf->get_canvas()->get_cpdf()->setEncryption('userpass', 'ownerpass', array('print'));
    }

IN VIEW TEMPLATE: `...

...`

Nexample-G commented 3 years ago

Just Replace ( dompdf\src\Image\Cache.php ) From dompdf 0.8.5 To All New Version Dompdf !

dompdf 0.8.5 : https://github.com/dompdf/dompdf/releases/tag/v0.8.5

you can see here : https://youtu.be/bM3y5TY-7_k

Name Address Contact number Primary Key