如何使用PHP为现有PDF文件添加水印?

时间:2010-05-26 14:38:30

标签: php

我需要使用PHP为现有PDF文件添加水印。我在Google上搜索过它,但找不到合适的图书馆。

我找到了创建PDF文件预览缩略图的fpdf库,但我不知道它是否会在现有PDF文件中添加水印。任何人都可以建议一个PHP库,而不是显示预览并为现有的PDF文件添加水印吗?

5 个答案:

答案 0 :(得分:10)

使用FPDF和FPDI类只是一个快速的例子:

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

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

$filename - 要在其中放置水印的PDF路径 $text - 要添加的水印文字
$x - 要在其中放置水印的x坐标 $y - 您想要放置水印的坐标 $opacity - 文字的不透明度 $directoutput - 如果TRUE函数将输出PDF文件,否则它将返回$ pdf
正如我已经说过的,这是一个非常快速和肮脏的例子,它需要一些改进。

答案 1 :(得分:6)

对于偶然发现此帖子的其他人,您可以使用for循环生成更多页面

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

答案 2 :(得分:1)

在马克的帮助下得到它我们去http://www.fpdf.de/downloads/addons/9/如果你们认为是的话我将把我的答案标记为胜利者。

感谢Jyelton对我的问题的回答看起来像stackover flow是无效的....

答案 3 :(得分:1)

    /* 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();
    }

}

从fpdf示例脚本中尝试this.modified脚本。 编辑:添加不透明度使用$ this-&gt; SetAlpha(0.5)

答案 4 :(得分:0)

这是一种MPDF的做法,在面向横向的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();
  • 花了我一段时间使输出结果正确大小,最后发现关键是您需要为要编写的实例指定宽度和高度。就我而言,输入的PDF文件可能具有不同的大小,因此在编写文件之前,我必须启动另一个实例以获取大小。

  • 如果您的PDF版本高于1.4, PDFI将无法使用。 您必须将其转换为1.4。我在Laravel工作中使用xthiago/pdf-version-converter