dompdf / dompdf

HTML to PDF converter for PHP
https://dompdf.github.io/
GNU Lesser General Public License v2.1
10.47k stars 1.79k forks source link

White space in data-uri mime type breaks image rendering #1386

Open Asimov500 opened 7 years ago

Asimov500 commented 7 years ago

I have some images outside my root folder which I need to display inside dompdf. I also use the same method for displaying private company images on the webpage. I have a whole function for doing this but I will just display the bare bones code. The problem is that the image is showing as unknown. I have double checked the path is correct, and even tried putting the full path in.

$imageData = base64_encode(file_get_contents($image));
$finfo = new finfo();
$fileinfo = $finfo->file($image, FILEINFO_MIME);
$src = 'data: '.$fileinfo.';base64,'.$imageData;
echo'<img class="headpic" src="'.$src.'"/></a>';

This is only the cutdown code. There is a lot in my code which isn't relavent here. The $image is the path, plus the image outside the root folder. Anyway I tried it inside the root, and still the image doesn't show.

I did however paste the base64 image straight in, and that worked, but other than that it won't show when I use filegetcontents.

I have also tried jpgs, and pngs and I get the same. It is a big problem, because we really need to load the external content into a pdf.

Asimov500 commented 7 years ago

I have solved the problem and I believe I should post the solution here to help others. The problem is this line $src = 'data: '.$fileinfo.';base64,'.$imageData; After echoing this variable without $imageData I get this data: image/png; charset=binary;base64,

It looks right doesn't it, and it works fine on a webpage, but take the same line into dompdf and it doesn't work. So I discover the space between image/png; and charset was stopping it working. So this is what I did.

$imageData = base64_encode(file_get_contents($image));
$finfo = new finfo();
$fileinfo = $finfo->file($image, FILEINFO_MIME);
$src = 'data: '.$fileinfo.';base64,'.$imageData;
$src=str_replace(" ","",$src);
echo'<img src="'.$src.'"/>';

I did an str_replace to remove all spaces in the string, and now the images show. So instead of getting this

<img width='150px' src='data:image/jpeg; charset=binary;base64,".$imageData."'>

I am now getting this

<img width='150px' src='data:image/jpeg;charset=binary;base64,".$imageData."'>

Obvioiusly the space doesn't bother it when it renders on a webpage, but in dompdf even one space will stop the image loading. I hope this helps someone, and I wonder if dompdf could be slightly re-written to remove all spaces in an image tag or something.

I haven't closed the issue because I believe if a webpage can render a base64 image with spaces, then I believe dompdf should also be able to do this. If this is in the pipeline and somebody says that this will be solved at some point, I will gladly close the issue.

bsweeney commented 7 years ago

There does appear to be an inconsistency there when compared to browser functionality. We'll look into it.

fillmore-admin commented 5 years ago

Did this ever happen? I'm trying to show an image in a PDF with needing internet.

$type = pathinfo($path, PATHINFO_EXTENSION); $data = file_get_contents($path); $base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);

echo '';

Asimov500 commented 5 years ago

Hi fillmore, Haven't used dompdf for a while because the new company I work for uses tcpdf. I actually prefer dompdf of course. Use

$imageData = base64_encode(file_get_contents($image));
$finfo = new finfo();
$fileinfo = $finfo->file($image, FILEINFO_MIME);
$src = 'data: '.$fileinfo.';base64,'.$imageData;

rather then just getting the extension. Sometimes people rename files as png when they are really a jpg.

bsweeney commented 4 years ago

We never addressed this particular issue, no, though we addressed a similar issue in #1016.

It doesn't look like the spec (rfc2397) indicate spaces are allowed in the non-data component of the data-uri. The data portion would allow for it depending on the encoding (e.g. base64 rfc2045).

Still, we'll take a look at a minor enhancement for the next release. As noted in MDN:

A data URL provides a file within a file, which can potentially be very wide relative to the width of the enclosing document. As a URL, the data should be formatable with whitespace (linefeed, tab, or spaces), but there are practical issues that arise when using base64 encoding.

So, assuming you have any spaces in your data-uri try removing them.