我需要使用PHP为现有PDF文件添加水印。我在Google上搜索过它,但找不到合适的图书馆。
我找到了创建PDF文件预览缩略图的fpdf库,但我不知道它是否会在现有PDF文件中添加水印。任何人都可以建议一个PHP库,而不是显示预览并为现有的PDF文件添加水印吗?
答案 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。