前言

在使用 PHP 在 PDF 文件上打水印的过程中,我尝试了如下几个工具:

因为想满足对中文水印的支持,并对 PDF 文档进行加密,最终使用 FPDI + TCPDF 的方案完成功能。

正文

打水印类1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106require_once ('./fpdi/TCPDF/tcpdf.php');

require_once('./fpdi/fpdi.php');

class extends FPDI{

protected $angle = 0;

protected $extgstates = array();

public function __construct(){

parent::__construct();

}

/**

* 旋转角度

* @param $angle

* @param int $x

* @param int $y

*/

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

}

}

/**

* 旋转文字角度

* @param $x

* @param $y

* @param $txt

* @param $angle

*/

public function RotatedText($x, $y, $txt, $angle)

{

$this->_rotate($angle,$x,$y);

$this->Text($x,$y,$txt);

$this->_rotate(0);

}

/**

* 旋转图片角度

* @param $file

* @param $x

* @param $y

* @param $w

* @param $h

* @param $angle

*/

public function RotatedImage($file, $x, $y, $w, $h, $angle)

{

//Image rotated around its upper-left corner

$this->_rotate($angle,$x,$y);

$this->Image($file,$x,$y,$w,$h);

$this->_rotate(0);

}

/**

* 设置字体颜色

* @param $hexStr

*/

public function SetTextColorByHexStr($hexStr){

$rgbArray = $this->_hex2rgb($hexStr);

if (is_array($rgbArray)) {

$this->SetTextColor($rgbArray['red'], $rgbArray['green'], $rgbArray['blue']);

}

}

/**

* 16进制颜色代码转RGB值

* @param string $hexStr (hexadecimal color value)

* @param boolean $returnAsString (if set true, returns the value separated by the separator character. Otherwise returns associative array)

* @param string $seperator (to separate RGB values. Applicable only if second parameter is true.)

* @return array or string (depending on second parameter. Returns False if invalid hex color value)

*/

protected function _hex2rgb($hexStr, $returnAsString = false, $seperator = ','){

$hexStr = preg_replace("/[^0-9A-Fa-f]/", '', $hexStr); // Gets a proper hex string

$rgbArray = array();

if (strlen($hexStr) == 6) { //If a proper hex code, convert using bitwise operation. No overhead... faster

$colorVal = hexdec($hexStr);

$rgbArray['red'] = 0xFF & ($colorVal >> 0x10);

$rgbArray['green'] = 0xFF & ($colorVal >> 0x8);

$rgbArray['blue'] = 0xFF & $colorVal;

} elseif (strlen($hexStr) == 3) { //if shorthand notation, need some string manipulations

$rgbArray['red'] = hexdec(str_repeat(substr($hexStr, 0, 1), 2));

$rgbArray['green'] = hexdec(str_repeat(substr($hexStr, 1, 1), 2));

$rgbArray['blue'] = hexdec(str_repeat(substr($hexStr, 2, 1), 2));

} else {

return false; //Invalid hex color code

}

return $returnAsString ? implode($seperator, $rgbArray) : $rgbArray; // returns the rgb string or the associative array

}

}

继承顺序

程序依赖 FPDI 读取已存在的 PDF 文档,依赖 TCPDF 处理 PDF 文档。程序继承顺序如下:Pdf_Watermark extends FPDI

FPDI extends FPDF_TPL

FPDF_TPL extends fpdi_bridge

fpdi_bridge 根据引入的类是 TCPDF 还是 FPDF 进行选择继承

因此,在使用 FPDI 读取文件后,可以选择使用 TCPDF 或 FPDF 对文档进行处理。

调用方法1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59require_once('PdfWatermark.php');

function pdf_set_watermark_text($file, $newFile, $text, $text_color, $font_style, $font_size, $alpha, $margin_left, $margin_top, $angle){

try {

$pdf = new Pdf_Watermark();

$pageCount = $pdf->setSourceFile($file);

// 循环读取分页

for ($i = 1; $i <= $pageCount; $i++) {

// 加密文档

$pdf->SetProtection(array('print', 'modify', 'copy', 'annot-forms'));

$pdf->addPage();

$tplidx = $pdf->importPage($i);

// 获取 pdf 长宽

$whArray = $pdf->getTemplateSize($tplidx);

$pdfWidth = $whArray['w'];

$pdfHeight = $whArray['h'];

// 如果将最后一个参数 $adjustPageSize 设置为TRUE,则当前的pdf页面大小会根据模板自适应。

$pdf->useTemplate($tplidx, null, null, 0, 0, TRUE);

for ($j = 0; $j < 9; $j++) {

// 设置字体

$pdf->SetFont('helvetica', 'B', $font_size);

$pdf->SetAlpha($alpha);

// 设置文字颜色

$pdf->SetTextColorByHexStr($text_color);

// 设置文字位置

$pdf->RotatedText($margin_left+$j*30, $margin_top+$j*30, $text, $angle);

$pdf->SetAlpha(1);

}

}

// pdf文档在浏览器中输出显示

$pdf->Output($newFile, 'I');

} catch (Exception $ex) {

return false;

}

return true;

}

$pdfFile = 'test.pdf';

$newFile = 'word.pdf';

$watermark_text = 'abc';

$text_color = '#CFCFCF';

$font_style = 'B';

$font_size = 25;

$alpha = 0.5;

$margin_left = 10;

$margin_top = 10;

$angle = 45;

pdf_set_watermark_text($pdfFile, $newFile, $watermark_text, $text_color, $font_style, $font_size, $alpha, $margin_left, $margin_top, $angle);

FPDI的限制

FPDI 的免费版本只能读取版本 <1.5 的 pdf 文档,为了兼容所有的 pdf 文档需要做一些处理。

如果不在乎 money,可以直接使用付费工具 FPDI PDF-Parser 来解决这个问题。

我在这里选择了使用 PDFtk 命令行工具,通过在 PHP 中执行如下代码对 pdf 文档进行处理:1exec("pdftk input_file.pdf output output_file.pdf");

这样,处理过后的 output_file.pdf 就能使用上诉方法添加水印了。

关于中文显示

新版本的 TCPDF 已支持中文,在 TCPDF/fonts 目录下存在 cid0cs.php 与 stsonstdlight.php 均能有效支持中文显示。

可以使用 setFont 方法进行调用:1

2// 设置字体

$pdf->SetFont('cid0cs', '', $font_size);1

2// 设置字体

$pdf->SetFont('stsongstdlight', '', $font_size);

总结

在研究给 PDF 文档打水印的过程中一波三折。

因为一开始选用的 FPDF 不支持 utf-8 编码,转战 TFPDF 开始捣鼓中文字体包,最终因为需要加密文档选择了更加方便的 TCPDF。

总的来说,开发前还是要仔细阅读参考文档啊,泪目。

参考资料

php生成pdf水印,使用 PHP 在 PDF 文档中加水印并进行文档加密相关推荐

  1. ionic4 select 去掉确定取消按钮_word文档中的水印如何去掉,有三种方法,你最喜欢哪种?...

    我们经常发现一些文档中有水印,有时需要将这个水印删除,有些小伙伴就不知道如何去掉,今天,飞云老师教大家三种方法,快速去掉word文档中的水印. 方法1:"借助页眉"法 具体操作:在 ...

  2. word加水印铺满java,Word 2010文档中让水印铺满整个页面的设置方法

    在Word 2010中,通过简单的鼠标单击即可为文档添加水印,但这样只能在每一个文档页面内添加一个水印,这个在前面的文章已经有所介绍,具体请见:Word文档添加内置水印.个性化图片及文字水印的方法,但 ...

  3. PPT中加水印的方法

    PPT中加水印的方法网上介绍的比较多的是在PPT母版中加艺术字的方法,这种方法有时候只能对部分页面加上水印,且艺术字的透明度无法调节,非常不方便,本人介绍另外一种PPT加水印的方法: 插入->艺 ...

  4. word文档中的水印怎样去除?这三个方法教大家快速搞定!

    在一些word文档中我们经常可以见到带有水印,但是有的时候,我们遇到这些问题却不知道从哪里下手去除掉它.今天小编给大家分享几种去除水印的方法,希望可以帮助到大家. 方法一:直接去除水印 当我们的wor ...

  5. word文字铺满页面_Word 2010文档中让水印铺满整个页面的设置方法

    在Word 2010中,通过简单的鼠标单击即可为文档添加水印,但这样只能在每一个文档页面内添加一个水印,这个在前面的文章已经有所介绍,具体请见:Word文档添加内置水印.个性化图片及文字水印的方法,但 ...

  6. 再见水印软件!2行Python给图片加水印,太太太强了

    人生苦短,快学Python! 版权相当重要,对于某张图片,可能是你精心制作的思维导图,或者你精心设计的某个logo.你可能花费好多时间来弄,最后却被别人直接搬运过去使用,好气哦! 基于此,本文我就带着 ...

  7. android 小视频添加水印,安卓手机怎么给视频加水印 视频加水印的手机软件|微信小视频怎么加水印...

    感觉中午一个小时的午休时间更本不够似的,以至于现在的我还头昏脑胀的厉害,睡眼惺忪的我还得默默的敲击着键盘,全都是为了生活啊,算了不传递这些负能量了,来说说咱们今天的教程,是关于如何用手机给视频加水印的 ...

  8. html中加水印,静态html页面 添加水印效果 且 水印不可复制

    1 2 3 4 5 //调整iframe高度 6 functioniFrameHeight() {7 varifm=document.getElementById("iframepage&q ...

  9. 给图片加上水印php视频,如何使用PHP给图片加水印

    为了防止辛苦做出来的图片被盗用,很多照片都会加上水印,可以直接用图片工具添加水印再上传,但PHP中就可以实现给图片加水印的功能,本文章向码农们介绍 php 给图片加水印的两种方法,感兴趣的码农可以参考 ...

最新文章

  1. 疫情严重!国内互联网公司上班时间汇总!
  2. url 百分号 解码
  3. wxWidgets:菜单
  4. 简单线性回归预测实现
  5. 使用Javascript 获得Word application的版本号
  6. 细数黑客攻击的七大战术
  7. Java8 中的 Optional
  8. DDoS分布式拒绝服务攻击简介
  9. win10系统资源管理器打开反应很慢如何解决
  10. 【GNN】图网络|图神经网络(GNN)结构化数据分析
  11. GD32F105V开发过程中的管脚配置问题记录
  12. Oracle JDK 终于免费了!网友:are you sure?
  13. 自己写的年会抽奖软件免费版带后门作弊,共享出来给大家(更新至V1.3)——转自哈尔滨健康生活网
  14. windows 98 设置 TEMP 环境变量时的一个有趣现象
  15. 根据百度地图进行IP定位获取地址
  16. kiwi syslog安装部署中的问题
  17. 案例分析——快手百万在线直播
  18. 推荐几个学术工具软件给大家
  19. 【Leetcode刷题Python】494. 目标和
  20. 计算机系统验证供应商评估,计算机化系统验证条款解读

热门文章

  1. EZ简介、搜索及其破解及经验
  2. IDEA搭建泛微OA Ecology 9.0 开发环境 (Windows版)
  3. 2020FME博客大赛——FME在数据整合中的应用
  4. 433M串口模块无线通信(STM32)
  5. 广电收视率项目之项目需求分析
  6. 基于HSV空间的光影检测
  7. Android屏幕点亮(常亮)及屏幕解锁和锁定
  8. linux mic阵列通道丢数据,基于XMOS平台的USB麦克风阵列多声道采集装置
  9. html语言制作个人简介,个人简介网页制作模板代码技术分享
  10. EMC (电磁兼容性)