文章目录

  • 裁剪pdf
  • 使用脚本拆分页面并转成kindle可见的大小
  • 压缩pdf
  • (可选) 拆分pdf

由于买了个kindle,所以想要最大效率地利用它。而在kindle上看pdf是很难受的,因为kindle屏幕太小,展示一个页面字体基本看不清。
因此,我写了个python脚本,配合acrobat使用能够把原始的pdf,尤其是A4页面格式的pdf转换成kindle看着舒适的pdf。使用方法如下

裁剪pdf

使用acrobat等软件对相应的pdf进行裁剪,尽量多得去除白边。这样在kindle上才能看到尽量大的文字

对于文字版pdf,白边界限很清楚,可以使用pdf-xchange editor,然后文档->裁剪页面->设为空白外边框,然后点全部页面。此时能够自动去除白边,效果非常好

使用脚本拆分页面并转成kindle可见的大小

脚本如下:

import os
import PyPDF2
from multiprocessing import Process
import shutil"""
将pdf文件切割成kindle可看的大小
"""class PDF2Kindle(object):"""PDF到kindle阅读的类"""  def FillPage(self,page,ws,hs):"""这里本来想要做成如果剩下想要拆分的页面不够铺满想要的大小,则在后面填充空白,试了几次都失败了,不过可以凑合用params:page,页面句柄ws,int,标准宽度hs,int,标准高度return:new_page,新的页面句柄"""# blank = page.createBlankPage(width=ws,height=hs)# if self.crosswise:#     blank.rotateCounterClockwise(90)# blank.mergePage(page)return pagedef CropPage(self,pdf_writer,page,page_idx):"""读取图片,裁剪为标准大小,并输出为pdfparams:pdf_writer,读取的pdf文件句柄page,该页面句柄return:pdf_writer,返回的pdf文件句柄,FIXME 可能用不到page_num,int,页数"""all_crops = []if self.crosswise:ws = self.hshs = self.wselse:ws = self.wshs = self.hsw = float(page.mediaBox.getUpperRight_x())h = float(page.mediaBox.getUpperRight_y())cwbeg = float(page.cropBox.getLowerLeft_x())chbeg = float(page.cropBox.getLowerLeft_y())cwend = float(page.cropBox.getUpperRight_x())chend = float(page.cropBox.getUpperRight_y())print("Generating %s page %d, shape=(%d,%d) ..." % (self.read_full_name,page_idx+1,w,h))scale = ws/(cwend-cwbeg)page.scaleBy(scale)cwbeg *= scalechbeg *= scalecwend *= scalechend *= scalepage.cropBox.lowerLeft=(cwbeg,chbeg)page.cropBox.upperRight=(cwend,chend)if self.crosswise:page.rotateCounterClockwise(90)#进行分割hend = chendcnt = 0while hend > chbeg:new_page = pagenew_page.cropBox.upperRight= (cwend,hend)new_page.cropBox.lowerLeft = (cwbeg,max(chbeg,hend-hs))if hend-chbeg<=hs:new_page = self.FillPage(new_page,ws,hs)#0.97表示连续两张拆分页面之间有3%的重叠hend -= hs*0.97#写入其中一个pdf并读取为单独的一页tmp_writer = PyPDF2.PdfFileWriter()tmp_writer.addPage(new_page)tmp_page_idx = "%03d" % page_idxtmp_cnt_idx = "%03d" % cnttmp_fn = self.tmppath + '/' + self.read_fn + '_' + tmp_page_idx + '_' + tmp_cnt_idx + '.pdf'#判断是否有tmppathif not os.path.exists(self.tmppath):os.mkdir(self.tmppath)tmp_writer.write(open(tmp_fn, "wb"))#再读取回来加入到all_cropstmp_reader = PyPDF2.PdfFileReader(open(tmp_fn, "rb"))tmp_page = tmp_reader.getPage(0)#保存crop_im到pdf中?all_crops.append(tmp_page)cnt += 1#已分割完成,放入pdf中page_num = len(all_crops)for p in all_crops:pdf_writer.addPage(p)return pdf_writer,page_numdef BatchConvertPDF(self,std_shape,crosswise,read_full_name,writepath,tmppath):"""将一个目录下的所有图片均转化成拼接好的pdf"""read_only_path,read_file_full_name = os.path.split(read_full_name)read_fn,read_ext = os.path.splitext(read_file_full_name)write_fn = writepath + '/' + read_fn(self.ws,self.hs) = std_shapeself.crosswise = crosswiseself.read_full_name = read_full_nameself.read_fn = read_fnself.tmppath = tmppathself.write_fn = write_fn#按页转化页面pdf_reader = PyPDF2.PdfFileReader(open(self.read_full_name, "rb"))pdf_writer = PyPDF2.PdfFileWriter()pdf_reader_page_num = pdf_reader.getNumPages()cur_cnt = 0page_cnt = 0start_cnt = 1for i in range(pdf_reader_page_num):#转化为标准页面page = pdf_reader.getPage(i)_,page_num = self.CropPage(pdf_writer,page,i)#merge并添加书签bookmark_str = '%03d' % (i+1)pdf_writer.addBookmark(bookmark_str,page_cnt)#更新标签cur_cnt +=1page_cnt +=page_num#如果达到上限,则写入pdfif i==pdf_reader_page_num-1:start_str = '%03d' % start_cntend_str = '%03d' % (i+1)#写文件full_name = write_fn + '.pdf'print("Write %s..." % full_name)pdf_writer.write(open(full_name, "wb"))#重置索引cur_cnt = 0start_cnt = i+2page_cnt = 0#新建pdf_mergerpdf_writer = PyPDF2.PdfFileWriter()def ProcessPDF2Kindle(args):"""子进程,处理PDF2Kindle"""pdf2k = PDF2Kindle()pdf2k.BatchConvertPDF(std_shape=args['std_shape'],crosswise=args['crosswise'],read_full_name=args['read_full_name'],writepath=args['writepath'],tmppath=args['tmppath'])def DeleteDIR(dirname):"""删除路径params:dirname,str,路径名"""if not os.path.exists(dirname):returnshutil.rmtree(dirname)if __name__ == '__main__':"""params:std_shape,tuple,标准形状,形式为(width,height), eg. (525,640) in kindle, and (1072,1440) in kpw3crosswise,binary,是否要横向阅读,字体会大一些read_full_name,str,读取的文件的路径writepath,str,写入的路径tmppath,str,tmppdf的路径"""args = {'std_shape':(536,720),#需要转换的分辨率,对于kindle来说,这个分辨率正合适'crosswise':True,#是否横着看,横着看字体会比竖着看大一些'read_full_name':'bbb.pdf',#需要转换的pdf'writepath':'write','tmppath':'tmp'#需要提供一个tmp文件夹缓存pdf}#这里因为pdfread需要手动open一些文件,这里懒得再一个一个close了,所以添加一个线程自动closep = Process(target=ProcessPDF2Kindle,args=(args,))#pdf2kindlep.start()p.join()#删除tmp文件夹DeleteDIR(args['tmppath'])

修改上面代码中的read_full_name参数,然后运行该文件,得到裁剪后的pdf,放在write文件夹中

注意:对于某些pdf在转换时会出现编码问题,这个目前还无法解决

压缩pdf

此时pdf文件大小偏大,可以使用acrobat打开该文件,然后,文件->另存为其他->缩小大小的pdf,有效降低pdf文件的大小

(可选) 拆分pdf

如果文件还是偏大,或者页面偏多,则可以选择对pdf进行拆分,拆分代码如下:

import os
import PyPDF2
from multiprocessing import Process"""
对于使用pdf_to_kindle的文件,使用该文件来进行分割
"""class SlicePDF(object):"""PDF到kindle阅读的类"""  def GetBookmark(self,pdf_reader):"""得到pdf中所有的书签params:pdf_reader,PdfFileReader句柄return:all_bookmarks,list"""#添加pdf所有的索引total_idx = {}page_all_idx = pdf_reader.getPage(0)['/Parent']['/Kids']for i,idx in enumerate(page_all_idx):idnum = idx.idnumidnum = str(idnum)total_idx[idnum] = i#寻找每个大页面对应的小页面ori_bm = pdf_reader.outlinesall_bookmarks = []for item in ori_bm:idx = item.pageidnum = idx.idnumidnum = str(idnum)page = total_idx[idnum]all_bookmarks.append(page)return all_bookmarksdef BatchConvertPDF(self,read_full_name,writepath,con_num):"""将一个目录下的所有图片均转化成拼接好的pdf"""read_only_path,read_file_full_name = os.path.split(read_full_name)read_fn,read_ext = os.path.splitext(read_file_full_name)write_fn = writepath + '/' + read_fnself.read_full_name = read_full_nameself.read_fn = read_fnself.write_fn = write_fnif con_num <1:print("con_num must >=1")quit()#寻找每个大页面对应的小页面pdf_reader = PyPDF2.PdfFileReader(open(self.read_full_name, "rb"))all_bookmarks = self.GetBookmark(pdf_reader)#进行分割pdf_writer = PyPDF2.PdfFileWriter()all_reader_num = pdf_reader.getNumPages()ori_page_num = len(all_bookmarks)sub_page = 0start_page = 1for i in range(ori_page_num):#找到该大页的所有小页面beg_page = all_bookmarks[i]if i == ori_page_num-1:end_page = all_reader_numelse:end_page = all_bookmarks[i+1]#添加该大页的所有页面for page_idx in range(beg_page,end_page):page = pdf_reader.getPage(page_idx)pdf_writer.addPage(page)#添加书签bookmark_str = '%03d' % (i+1)pdf_writer.addBookmark(bookmark_str,beg_page-sub_page)#如果达到上限,则写入pdfif (i+1)%con_num==0 or i == ori_page_num-1:start_str = '%03d' % start_pageend_str = '%03d' % (i+1)if con_num == 1:full_name = write_fn +  '_' + start_str + '.pdf'else:full_name = write_fn +  '_' + start_str + '_' + end_str  + '.pdf'print("Write %s..." % full_name)pdf_writer.write(open(full_name, "wb"))#更新参数if i != ori_page_num-1:start_page = i+2sub_page = all_bookmarks[i+1]#新建pdf_mergerpdf_writer = PyPDF2.PdfFileWriter()def ProcessSlicePDF(args):"""子进程,处理PDF2Kindle"""pdf2k = SlicePDF()pdf2k.BatchConvertPDF(read_full_name=args['read_full_name'],writepath=args['writepath'],con_num=args['con_num'])if __name__ == '__main__':"""params:read_full_name,str,读取的文件的路径writepath,str,写入的路径con_num,int,每个pdf包含的页数,如果<=0则拼接全部的pdf,否则按照con_num来拼接"""args = {'read_full_name':'write/bbb.pdf', #修改这里为读入的文件'writepath':'write','con_num':10 #修改这里为拆分pdf每页的大小}p = Process(target=ProcessSlicePDF,args=(args,))#pdf2kindlep.start()p.join(

注意:读入的pdf一定是第一个脚本处理过的pdf,否则可能报错

修中的read_full_name为要读入的pdf文件,con_num表示每多少页拆分成一个文件,其中每页代表最原始的pdf的页面,然后运行该文件,则得到拆分后的pdf

使用pypdf2把原始pdf转换成kindle看着舒适的pdf相关推荐

  1. pdf转换成html python,在Python中将pdf转换为html

    Python 2.6 我试图解析我的pdf文件,其中一种方法是将其转换为html并提取标题和段落. 所以,我尝试了pdf2htmlEX,它将我的pdf转换成html格式,而不干扰我的pdf格式...到 ...

  2. 如何将PDF转换成JPG——speedPDF在线免费批量PDF转JPG

    怎么免费将PDF格式的文件转成JPG格式的呢,看看小编是用的什么方法吧. 首先,推荐一款名的speedPDF的在线转换,网址为:https://speedpdf.com,打开后页面如图所示: 然后,选 ...

  3. pdf转换成txt转换器在线转换

    PDF.TXT.Word.Excel和Word格式文件是我们我们日常办公中使用频率最高的,有时我们需要将PDF转换成为更加便捷打印编辑的TXT和Word文档,而面对这两种不同格式的转换,很多用户都试图 ...

  4. 完美PDF转换成Word转换器

    网络上存在众多的PDF转换成Word转换器,为什么大部分都无法完美转换PDF文件?大部分的转换器转换之后的Word文件当中,很多内容上都存在不少问题,例如文字缺乏.识别错误.图片不全等,最终导致用户不 ...

  5. 图文混合PDF转换成Word方法介绍 PDF转换器下载

    PDF文件本身易于阅读难以编辑的特点,使得不少办公用户不得不考虑将PDF文件内容转换成为Word文件格式.借助迅捷PDF转换成Word转换器的强大转换功能,即便是普通电脑用户也可以轻松上手操作,无需做 ...

  6. 批量PDF转换成Office文件 PDF转换器下载

    2019独角兽企业重金招聘Python工程师标准>>> 迅捷PDF转换成Word转换器采用了最新的一代的增强版核心技术,除了加强原超线程批量转换技术之外,新版本还提升了软件的多文件格 ...

  7. android开发将h5转换成pdf_一键将PDF转换成PPT,秒懂!

    PDF因能良好的兼容各操作系统和软件版本的差异性,使得PDF文档在查阅播放的时候不影响排版变化,很多时候,我们因为工作上的需要,经常需要再次将PDF转换成PPT,那么怎样将PDF转换成PPT呢?需要下 ...

  8. python pdf转txt保留全部信息_Python 将pdf转换成txt(不处理图片)

    上一篇文章中已经介绍了简单的python爬网页下载文档,但下载后的文档多为doc或pdf,对于数据处理仍然有很多限制,所以将doc/pdf转换成txt显得尤为重要.查找了很多资料,在linux下要将d ...

  9. PDF转换成word免费

    PDF文档如何转换成Word格式的?大家多多少少都会遇到这样的问题,比如在网上下载论文资料.电子书等文件时,会发现资料都是PDF格式的.下载后却不能复制编辑,这种情况太让人沮丧了吧!PDF格式的文件在 ...

最新文章

  1. Android之退出应用关闭项目每个Activity的总结
  2. 解决:RabbitMQ 连接报错:amqp.AmqpConnectException: java.net.ConnectException: Connection refused: connect
  3. mysql-8.0.16-winx64.zip安装教程
  4. SSL For Free 免费 SSL 凭证申请 Let’s Encrypt
  5. 使用RecyclerView替代ListView(一)
  6. latex longtable caption长度提前换行解决方案
  7. Oracle使用sqluldr2
  8. python读取scv文件显示:OSError: Initializing from file failed
  9. 经纬度坐标相互转换度分秒
  10. java 过滤微信昵称_java过滤微信昵称特殊字符
  11. linux7找回删除的文件,centos7 rm -rf 删除文件的找回
  12. Ajax学习日志(五)—— 如何传递json格式请求参数
  13. 每天花2小时学习5大学习网站!
  14. 【算法学习笔记】64. 枚举法 SJTU OJ 1381 畅畅的牙签
  15. 使用PlayCanvas制作一个简单的小游戏(二)
  16. TCGA 临床数据 表型 phenotype 各列的含义
  17. VB standard-module bas文件 调用
  18. Java面试必备240个知识点
  19. iphone 刷机遇到的一些名词解释
  20. 【小样本实体识别】Few-NERD——基于N-way K-shot的实体识别数据集和方法介绍

热门文章

  1. Java Web 实战 15 - 计算机网络之网络编程套接字
  2. u-boot-2014.10移植第3天----LED裸机程序
  3. 【计算机网络】数据链路层之随机接入-CSMA/CA协议(无线局域网)
  4. SSL P2293 暗黑游戏 题目
  5. XXX接口自动化测试方案
  6. 关于VSCode和electron系软件字体发虚/模糊的解决办法
  7. 我学习到的一些保险知识
  8. 腾讯qq中奖是真的吗_小程序真的救得了“中年危机”的QQ吗?
  9. java 姓排序_Java中先按照姓名排序在按照年龄排序 代码
  10. 手机拍花海,有没梦幻的赶脚?