I spent way too much time on this and I can't figure out a good 21th century solution.
Simply I have to generate a business card in PDF with a background image, but MPDF isn't very helpful.
By default I had:
@page{
sheet-size: 90mm 55mm;
margin: 0;
}
I tried to:
- use @page{ background-size: 100%; }
doesn't work
- use @page{ background-size: cover; }
doesn't work
- resize the image - even if I set the right size in 'mm', it will be smaller or larger, even if I set the background-image-resolution to the same value as the image.
- place absolute positioned
div
with background image
- same but with
img
tags, using src
attribute.
At the last option, I've got a really strange thing. It showed the whole image but in a small rectangle in the pages, but not even in full height.
Does anyone have an idea, how to simply use an image as a page background?
mPDF has a custom css property for background images: background-image-resize with custom values from 0-6:
- 0 - No resizing (default)
- 1 - Shrink-to-fit w (keep aspect ratio)
- 2 - Shrink-to-fit h (keep aspect ratio)
- 3 - Shrink-to-fit w and/or h (keep aspect ratio)
- 4 - Resize-to-fit w (keep aspect ratio)
- 5 - Resize-to-fit h (keep aspect ratio)
- 6 - Resize-to-fit w and h
So you probably need:
body {background-image:url(something.png); background-image-resize:6}
Taken from mPDF docs
In case anyone else needs a background-cover in mPDF and is not helped by background-image-resize, which breaks as soon as it is wrapped by a floated element. Floated elements are often necessary within mPdf because of the abscence of css compliance. Here is a more robust solution for a circled image, with bg-cover simulated.
Get image orientation
function getImageOrientation(string $imgPath){
list($imgWidth,$imgHeight) = getimagesize($imgPath);
$aspectRatio = $imgWidth / $imgHeight;
if($aspectRatio >= 1){
return array('landscape',$imgWidth,$imgHeight,$aspectRatio);
}else{
return array('portrait',$imgWidth,$imgHeight,$aspectRatio);
}
}
Set own properties to simulate background-cover
public static function returnCircledImage($imgPath, int $size){
list($orientation,$imgWidth,$imgHeight, $aspectRatio) = getImageOrientation($imgPath);
if($orientation == 'landscape'){
$backgroundSize = 'auto 100%'; //fit height, keep aspect ratio
$calculatedWidth = floor($size * $aspectRatio);
$calculatedHeight = $size;
//position center manually
$dx = -floor(($calculatedWidth - $calculatedHeight) / 2);
$dy = 0;
}else{
$backgroundSize = '100% auto'; //fit width, keep aspect ratio
$calculatedWidth = $size;
$calculatedHeight = floor($size * $aspectRatio);
//position center manually
$dx = 0;
$dy = -floor(($calculatedHeight - $calculatedWidth) / 2);
}
return sprintf('
<div class="%s" style="background-size: %s; background-position:%spx %spx; overflow:hidden; border-radius:100px; width:%spx; height:%spx; background-image: url(%s)"></div>
',
$backgroundSize,
$dx,
$dy,
$size,
$size,
$imgPath
);
}
Working example with the background-image-resolution
property :
<body style="background-image: url('/absolute/path/to/image.jpg');
background-position: top left;
background-repeat: no-repeat;
background-image-resize: 4;
background-image-resolution: from-image;">
It works fine with a 300DPI JPEG picture on invoices.
if you use both the style="..."
tag and a body{...}
style in CSS, mpdf will ignore the style="..."
tag and its content, so the picture will not appear!