前端处理现有的pdf

本文介绍如何在前端使用pdf-lib库处理现有的PDF文件,添加水印。内容涉及图片转换、PDF旋转及坐标适配等关键步骤,并提供了相关代码示例。
摘要由CSDN通过智能技术生成

前端处理现有的pdf

近期, 业务方希望能有一个工具能够给图片或者pdf加入水印.方便用户的使用.

分析一下需要的功能

  • 上传的 png, jpg 图片自动转换成pdf, 并加入水印
  • 上传的 pdf, 加入水印

功能上, 主要是对现有的pdf进行加入水印. 也就是修改pdf.

解决方案

awesome-javascript 在里面有常用的PDF处理库.
但是, 仅供参考. 还有一些优秀库, 它里面没有包含.

通过一番搜索和对比有3个库可能满足需求

  • jsPDF 生成pdf有许多方便的方法, 但是不支持修改现有的pdf.
  • pdfkit 生成pdf, 但是不支持修改现有的pdf.
  • pdf-lib 生成pdf有一些方法比较原始,需要自己适配. 支持修改现有的pdf.

综上, 选择了 pdf-lib

其中找到pdf-lib库, 还是通过在 jsPDF/issues/131 看到下面的

https://github.com/Hopding/pdf-lib is an alternative that can handle merging, splitting pages etc.
I’m using both libraries for different purposes.

pdf-lib

根据pdf-lib上的demo, 进行了实验.
发现还是挺简单的.

但是, 需要提醒几个点

坐标

左下角是原点

pdf旋转

pdf是可以旋转的. 但是一旦旋转之后, 可能水印的位置就不对了.
例如, 旋转90度.如图:
在这里插入图片描述

会导致原来的坐标位置就不对了.
需要自己适配一下

下面的我适配的代码, 仅供参考


// 如果传入的是负数, 就认为是距离边界多少
function getDistance(distance, offset) {
   
  if (offset < 0) {
   
    return distance + offset
  } else {
   
    return offset
  }
}

// 求弧度 角度 * Math.PI/180
function radian(angle){
   
  return angle * Math.PI /180
}

// 这里没有考虑pdf原本是宽要大于高的情况
// 代码应该考虑一些特殊情况, 和不能只适配90 180 270
// 应该可以写成 固定的公式
WatermarkPdf.getStartPoint = function (page, offset) {
   
  let rotation = page.getRotation()
  let width = Math.min(page.getHeight(), page.getWidth())
  let height = Math.max(page.getHeight(), page.getWidth())

  let angle = rotation.angle
  let x = 0
  let y = 0
  let {
    offsetX, offsetY } = offset

  // 宽高需要根据 angle 进行切换
  if (angle == 0) {
   
    x = getDistance(width, offsetX)
    y = getDistance(height, offsetY)
  }

  if (angle === 90) {
   
    x = getDistance(width, 0 - offsetY)
    y = getDistance(height, offsetX)
  }

  if (angle == 270) {
   
    x = getDistance(width, offsetY)
    y = getDistance(height, 0 - offsetX)
  }

  return {
    x, y }
}

jpg png

pdf-lib中没有对jpg和png自行适配.
而是需要我们自己进行图片格式的识别.

当用户上传文件后, 我们可以得到一个File类型的对象.
它继承了 Blob, 所以可以拿到ArrayBuffer. 也可以获取到文件的类型;
从而进行适配

可以看我的例子:

  async handleImage
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值