How can I add a watermark to an existing PDF file using PHP?

43,752

Solution 1

Just a quick'n'dirty example using FPDF and the FPDI Classes:

function PlaceWatermark($file, $text, $xxx, $yyy, $op, $outdir) {
    require_once('fpdf.php');
    require_once('fpdi.php');
    $name = uniqid();
    $font_size = 5;
    $ts=explode("\n",$text);
    $width=0;
    foreach ($ts as $k=>$string) {
        $width=max($width,strlen($string));
    }
    $width  = imagefontwidth($font_size)*$width;
    $height = imagefontheight($font_size)*count($ts);
    $el=imagefontheight($font_size);
    $em=imagefontwidth($font_size);
    $img = imagecreatetruecolor($width,$height);
    // Background color
    $bg = imagecolorallocate($img, 255, 255, 255);
    imagefilledrectangle($img, 0, 0,$width ,$height , $bg);
    // Font color
    $color = imagecolorallocate($img, 0, 0, 0);
    foreach ($ts as $k=>$string) {
        $len = strlen($string);
        $ypos = 0;
        for($i=0;$i<$len;$i++){
            $xpos = $i * $em;
            $ypos = $k * $el;
            imagechar($img, $font_size, $xpos, $ypos, $string, $color);
            $string = substr($string, 1);      
        }
    }
    imagecolortransparent($img, $bg);
    $blank = imagecreatetruecolor($width, $height);
    $tbg = imagecolorallocate($blank, 255, 255, 255);
    imagefilledrectangle($blank, 0, 0,$width ,$height , $tbg);
    imagecolortransparent($blank, $tbg);
    if ( ($op < 0) OR ($op >100) ){
        $op = 100;
    }
    imagecopymerge($blank, $img, 0, 0, 0, 0, $width, $height, $op);
    imagepng($blank,$name.".png");
    // Created Watermark Image
    $pdf = new FPDI();
    if (file_exists("./".$file)){
        $pagecount = $pdf->setSourceFile($file);
    } else {
        return FALSE;
    }
    $tpl = $pdf->importPage(1);
    $pdf->addPage();
    $pdf->useTemplate($tpl, 1, 1, 0, 0, TRUE);
    //Put the watermark
    $pdf->Image($name.'.png', $xxx, $yyy, 0, 0, 'png');
    if ($outdir === TRUE){
        return $pdf->Output();
    } else {
        return $pdf;
    }
}

PlaceWatermark("filename.pdf", "This is a lazy, but still simple test\n This should stand on a new line!", 30, 120, 100,TRUE);

Usage: PlaceWatermark($filename, $text, $x, $y, $opacity, $directoutput);

$filename – The path of the PDF in which you want to put the Watermark
$text – The Watermark text you want to add
$x – x coordinate where you want to put the Watermark
$y – y coordinate where you want to put the Watermark
$opacity – Opacity of the text
$directoutput – If TRUE function will output a PDF File, else it will return the $pdf
As I already said, this is a very quick and dirty example, it needs some improvements.

Solution 2

For anyone else that stumbles upon this post you can generate more pages using a for loop

for($i=1; $i <= $pagecount; $i++) {   
     $tpl = $pdf->importPage($i);    
     $pdf->addPage();     
     $pdf->useTemplate($tpl, 1, 1, 0, 0, TRUE);    
     //Put the watermark  
     $pdf->Image($name.'.png', $xxx, $yyy, 0, 0, 'png');}   

Solution 3

Here is a MPDF practice, adding watermarks to every page of a landscape oriented PDF.

    //First, get the correct document size.
    $mpdf = new \Mpdf\Mpdf([
        'tempDir' => storage_path('app'),
        'orientation' => 'L'
    ]);

    $pagecount = $mpdf->SetSourceFile('[path]');

    $tplId = $mpdf->ImportPage(1);
    $size = $mpdf->getTemplateSize($tplId);

    //Open a new instance with specified width and height, read the file again
    $mpdf = new \Mpdf\Mpdf([
        'tempDir' => storage_path('app'),
        'format' => [$size['width'], $size['height']]
    ]);
    $mpdf->SetSourceFile('[path]');

    //Write into the instance and output it
    for ($i=1; $i <= $pagecount; $i++) { 
        $tplId = $mpdf->ImportPage($i);
        $mpdf->addPage();
        $mpdf->UseTemplate($tplId);
        $mpdf->SetWatermarkText('[Watermark Text]');
        $mpdf->showWatermarkText = true;
    }

    return $mpdf->output();
  • It took me a while to make the output result in correct size, and finally found the key is that you need to specify the width and height to the instance you are going to write. In my case, the input PDF files may have different sizes, so I have to initiate another instance for getting size before working on the writing one.

  • If your PDF version is newer than 1.4, PDFI will not work with it. You have to convert it to 1.4. I use xthiago/pdf-version-converter in my Laravel work.

Solution 4

got it by help of Mark here we go http://www.fpdf.de/downloads/addons/9/ if you guys think yes it is i will mark my answer as winner.

Thanks Jyelton for the answer to my question looks like stackover flow is inactive....

Solution 5

    /* index.php */
    require('rotation.php');

    class PDF extends PDF_Rotate{
            protected $_outerText1;// dynamic text
        protected $_outerText2;

        function setWaterText($txt1="", $txt2=""){
            $this->_outerText1 = $txt1;
            $this->_outerText2 = $txt2;
        }

        function Header(){
            //Put the watermark
            $this->SetFont('Arial','B',40);
            $this->SetTextColor(255,192,203);
                    $this->SetAlpha(0.5);
            $this->RotatedText(35,190, $this->_outerText1, 45);
            $this->RotatedText(75,190, $this->_outerText2, 45);
        }

        function RotatedText($x, $y, $txt, $angle){
            //Text rotated around its origin
            $this->Rotate($angle,$x,$y);
            $this->Text($x,$y,$txt);
            $this->Rotate(0);
        }
    }

    $file = "path/filename.pdf";// path: file name
    $pdf = new PDF();

    if (file_exists($file)){
        $pagecount = $pdf->setSourceFile($file);
    } else {
        return FALSE;
    }

   $pdf->setWaterText("w a t e r M a r k d e m o ", "s e c o n d L i n e o f t e x t");

  /* loop for multipage pdf */
   for($i=1; $i <= $pagecount; $i++) { 
     $tpl = $pdf->importPage($i);               
     $pdf->addPage(); 
     $pdf->useTemplate($tpl, 1, 1, 0, 0, TRUE);  
   }
    $pdf->Output(); //specify path filename to save or keep as it is to view in browser

 /* rotation.php */
    require('fpdf.php');
require('fpdi.php');
class PDF_Rotate extends FPDI
{
    var $angle=0;
    var $extgstates = array();

    function Rotate($angle,$x=-1,$y=-1)
    {
        if($x==-1)
            $x=$this->x;
        if($y==-1)
            $y=$this->y;
        if($this->angle!=0)
            $this->_out('Q');
        $this->angle=$angle;
        if($angle!=0)
        {
            $angle*=M_PI/180;
            $c=cos($angle);
            $s=sin($angle);
            $cx=$x*$this->k;
            $cy=($this->h-$y)*$this->k;
            $this->_out(sprintf('q %.5F %.5F %.5F %.5F %.2F %.2F cm 1 0 0 1 %.2F %.2F cm',$c,$s,-$s,$c,$cx,$cy,-$cx,-$cy));
        }
    }

    function _endpage()
    {
        if($this->angle!=0)
        {
            $this->angle=0;
            $this->_out('Q');
        }
        parent::_endpage();
    }

    function SetAlpha($alpha, $bm='Normal')
    {
        // set alpha for stroking (CA) and non-stroking (ca) operations
        $gs = $this->AddExtGState(array('ca'=>$alpha, 'CA'=>$alpha, 'BM'=>'/'.$bm));
        $this->SetExtGState($gs);
    }

    function AddExtGState($parms)
    {
        $n = count($this->extgstates)+1;
        $this->extgstates[$n]['parms'] = $parms;
        return $n;
    }

    function SetExtGState($gs)
    {
        $this->_out(sprintf('/GS%d gs', $gs));
    }

    function _enddoc()
    {
        if(!empty($this->extgstates) && $this->PDFVersion<'1.4')
            $this->PDFVersion='1.4';
        parent::_enddoc();
    }

    function _putextgstates()
    {
        for ($i = 1; $i <= count($this->extgstates); $i++)
        {
            $this->_newobj();
            $this->extgstates[$i]['n'] = $this->n;
            $this->_out('<</Type /ExtGState');
            foreach ($this->extgstates[$i]['parms'] as $k=>$v)
                $this->_out('/'.$k.' '.$v);
            $this->_out('>>');
            $this->_out('endobj');
        }
    }

    function _putresourcedict()
    {
        parent::_putresourcedict();
        $this->_out('/ExtGState <<');
        foreach($this->extgstates as $k=>$extgstate)
            $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
        $this->_out('>>');
    }

    function _putresources()
    {
        $this->_putextgstates();
        parent::_putresources();
    }

}

try this.modified script from fpdf example scripts. Edit : Added opacity use $this->SetAlpha(0.5)

Share:
43,752

Related videos on Youtube

Yasir
Author by

Yasir

Freelance Web Designer and Developer contact me here http://www.netcane.com

Updated on June 23, 2020

Comments

  • Yasir
    Yasir almost 4 years

    I am in need of adding a watermark to an existing PDF file using PHP. I have searched on Google for it, but couldn't find any suitable library.

    I found the fpdf library that creates preview thumbnails of PDF files, but I don't know if it adds watermarks to existing PDF files or not. Can anyone suggest a PHP library than can show preview and add watermarks to existing PDF files?

  • Jonas Lejon
    Jonas Lejon over 12 years
    The code only works on one page. How can I change the code to support more input pages?
  • R1CHY_RICH
    R1CHY_RICH about 8 years
    Only does page 1. To fix change $tpl = $pdf->importPage(1); $pdf->addPage(); $pdf->useTemplate($tpl, 1, 1, 0, 0, TRUE);
  • Jatin Dhoot
    Jatin Dhoot over 6 years
    Its a dead link.

Related