php 当用户尝试下载文件时在 pdf 文件上应用水印
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3983432/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Applying watermarks on pdf files when users try to download the files
提问by ryan
The solutions for my school's assignments all have waterstamps on the PDFs with our username on it.
我学校作业的解决方案在 PDF 上都有水印,上面有我们的用户名。
I was wondering if you guys know how to do something like that using PHP? Do they run a script prior to the download process?
我想知道你们是否知道如何使用 PHP 做类似的事情?他们是否在下载过程之前运行脚本?
Thanks.
谢谢。
采纳答案by symcbean
Although there are several very good PDF libs for PHP, if I were writing such a program I'd just shell out to run pdftkbut you' still need to generate your watermark.
尽管 PHP 有几个非常好的 PDF 库,但如果我正在编写这样的程序,我会直接运行pdftk,但您仍然需要生成水印。
$tempfile=tempnam();
system("pdftk input_file.pdf background watermark.pdf output $tempfile dont_ask", $errcode);
if (!$errcode && $ih=fopen($tempfile, 'r')) {
header('Content-Type: application/pdf');
fpassthru($ih);
fclose($ih);
} else {
print "Whoops";
}
unlink($tempfile);
回答by haknick
Needed to do this yesterday and here's how without any external non-PHP libs that need to be installed. The only 2 libs needed are both PHP libs and are easy to get.
昨天需要这样做,这里是不需要安装任何外部非 PHP 库的方法。唯一需要的 2 个库都是 PHP 库并且很容易获得。
- FPDF -> http://www.fpdf.org/latest version
- FPDI -> http://www.setasign.de/products/pdf-php-solutions/fpdi/downloads/(make sure to throw the fpdf_tpl.php file in the same folder as fpdi.php)
- FPDF -> http://www.fpdf.org/最新版本
- FPDI -> http://www.setasign.de/products/pdf-php-solutions/fpdi/downloads/(确保将 fpdf_tpl.php 文件与 fpdi.php 放在同一文件夹中)
Now you can use the class below to achieve watermarking
现在你可以使用下面的类来实现水印
/** MAKE SURE TO HAVE THE INCLUDES RUNNING PROPERLY */
require_once('FPDF/fpdf.php');
require_once('FPDI/fpdi.php');
class WaterMark
{
public $pdf, $file, $newFile,
$wmText = "STACKOVERFLOW";
/** $file and $newFile have to include the full path. */
public function __construct($file, $newFile)
{
$this->pdf =& new FPDI();
$this->file = $file;
$this->newFile = $newFile;
}
/** $file and $newFile have to include the full path. */
public static function applyAndSpit($file, $newFile)
{
$wm = new WaterMark($file, $newFile);
if($wm->isWaterMarked())
return $wm->spitWaterMarked();
else{
$wm->doWaterMark();
return $wm->spitWaterMarked();
}
}
/** @todo Make the text nicer and add to all pages */
public function doWaterMark()
{
$currentFile = $this->file;
$newFile = $this->newFile;
$pagecount = $this->pdf->setSourceFile($currentFile);
for($i = 1; $i <= $pagecount; $i++){
$this->pdf->addPage();
$tplidx = $this->pdf->importPage($i);
$this->pdf->useTemplate($tplidx, 10, 10, 100);
// now write some text above the imported page
$this->pdf->SetFont('Arial', 'I', 40);
$this->pdf->SetTextColor(255,0,0);
$this->pdf->SetXY(25, 135);
$this->_rotate(55);
$this->pdf->Write(0, $this->wmText);
$this->_rotate(0);
}
$this->pdf->Output($newFile, 'F');
}
public function isWaterMarked()
{
return (file_exists($this->newFile));
}
public function spitWaterMarked()
{
return readfile($this->newFile);
}
protected function _rotate($angle,$x=-1,$y=-1) {
if($x==-1)
$x=$this->pdf->x;
if($y==-1)
$y=$this->pdf->y;
if($this->pdf->angle!=0)
$this->pdf->_out('Q');
$this->pdf->angle=$angle;
if($angle!=0){
$angle*=M_PI/180;
$c=cos($angle);
$s=sin($angle);
$cx=$x*$this->pdf->k;
$cy=($this->pdf->h-$y)*$this->pdf->k;
$this->pdf->_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));
}
}
}
You now can run this as:
您现在可以将其运行为:
WaterMark::applyAndSpit($fileWithFullPath);
回答by galymzhan
There is an excellent opensource php library http://www.tcpdf.org/, I use it for all pdf generating tasks.
有一个优秀的开源 php 库http://www.tcpdf.org/,我将它用于所有 pdf 生成任务。
回答by jeenus
Here are the steps that I tried with water marking using fpdi:
以下是我尝试使用 fpdi 进行水标记的步骤:
<?php
use setasign\Fpdi\Fpdi;
use setasign\Fpdi\PdfReader;
function PlaceWatermark($file, $text, $xxx, $yyy, $op, $outdir) {
require_once('fpdi/vendor/autoload.php');
require_once 'fpdi/vendor/setasign/fpdf/fpdf.php';
function copyTransparent($src, $output)
{
$dimensions = getimagesize($src);
$x = $dimensions[0];
$y = $dimensions[1];
$im = imagecreatetruecolor($x,$y);
$src_ = imagecreatefrompng($src);
// Prepare alpha channel for transparent background
$alpha_channel = imagecolorallocatealpha($im, 255, 255, 255, 127);
imagecolortransparent($im, $alpha_channel);
// Fill image
imagefill($im, 0, 0, $alpha_channel);
// Copy from other
imagecopy($im,$src_, 0, 0, 0, 0, $x, $y);
// Save transparency
imagesavealpha($im,true);
// Save PNG
imagepng($im,$output,9);
imagedestroy($im);
}
$png = 'https://www.office-deals.nl/images/logo_60x37.png';
copyTransparent($png,"png.png");
$imageURL = 'png.png';
$imgWidth = 20;
$pdf = new FPDI();
if (file_exists("./".$file)){
$pagecount = $pdf->setSourceFile($file);
} else {
return FALSE;
}
for($i=1; $i <= $pagecount; $i++) {
$tpl = $pdf->importPage($i);
$pdf->addPage();
$pdf->useTemplate($tpl, 5, 5);
$pdf->Image($imageURL, $xxx, $yyy,'png');
}
if ($outdir === TRUE){
return $pdf->Output($file,'I');
} else {
return $pdf->Output();
}
}
$images='https://www.office-deals.nl/images/logo_60x37.png';
PlaceWatermark("laravel.pdf", $images, 180, 275, 100,TRUE);
?>