MPDF full page background

2019-03-13 00:05发布

问题:

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?

回答1:

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



回答2:

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


回答3:

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!



标签: mpdf