图片批量转pdf

2018/06/26 python

意外原因,获得了一份网络上流通传逻辑思维《关系攻略》的截图版本,全部是图片,极不方便阅读,所以打算把截图转为PDF格式,以下就是本次的的方法 参考 python长图片切割并转换为pdf

import os
import re
#from PIL import Image
from tqdm import tqdm  
from reportlab.pdfgen import canvas
from reportlab.lib.units import inch, cm
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Image, PageBreak
from reportlab.lib.pagesizes import A4,A3,A2,A1, legal, landscape
from reportlab.lib.utils import ImageReader
import PIL.ExifTags
from os import listdir
import time
from reportlab.lib.units import inch
import PIL.Image

#解决报错OSError: image file is truncated (9 bytes not processed)
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True

把文件从不同的文件夹里抓出来,同时将图片切成A4比例,并且给以图片编号

# 抓取文件的路径
filedir='../Desktop/未命名文件夹2/cuang/'
re=re.compile(r'.*?jpg')
# 保存抓取后的结果的路径
dstpath='../Desktop/未命名文件夹2/relation'
def mkdir_if_not_exist(path):
    if not os.path.exists(path):
        os.makedirs(path)
mkdir_if_not_exist(dstpath)
# 将文件切割成A4比例,并且保存
def splitimage(src, dstpath):
    global k #给图片排序
    img = PIL.Image.open(src)
    w, h = img.size
    height=w*297/210 #A4纸比例出的高度
    num=h/height+1#将分割出的图片数量
    index=1
    base_h=height #之后做图片切割的间隔
    s = os.path.split(src)#分割出路径和文件名
    if dstpath == '':
        dstpath = s[0]
    fn = s[1].split('.')
    basename = fn[0]#文件名
    postfix = fn[-1]#后缀名

    while (index < num):
        #print('The index is:', index,"height is ",height)
        box = (0, height-base_h, w, height)
        img.crop(box).save(os.path.join(dstpath, basename + '_' + str(index) + '_' +str(k)+'.' + postfix), img.format)
        height = height + base_h
        index = index + 1
        k =k +1
#查看一下遍历的顺序是否正确,如果上1~10+的话,最好1~9改为01~09,不然会遍历顺序会上1,10,11,12,2,3,
for root, dirs, files in tqdm(os.walk(filedir)):
    print(files)
# 图片抓取
k=0
for root, dirs, files in tqdm(os.walk(filedir)):
    for i in files:
        obpath=os.path.join(root,i)
        if re.match(obpath) !=None:
          splitimage(obpath, dstpath)  
94it [02:14,  1.43s/it]

dir2=’../Desktop/未命名文件夹2/pdftest’ dir3=’../Desktop/未命名文件夹2/pdftest2’

rm -rf ../Desktop/未命名文件夹2/relation/.DS_Store #针对mac,删除.DS_Store文件,

建议用ImageOptim进行优化图片,压缩至50%,几乎不影响质量

  • 压缩比例最多可以压缩50%;
  • 压缩速度快
  • 支持批量压缩
  • 免费

将图片转换为pdf

方法一:reportlab 批量将图片转为PDF

def rotate_img_to_proper(image): #如果图片打开是被旋转了,则需要纠正
    try:
        # image = Image.open(filename)
        if hasattr(image, '_getexif'):  # only present in JPEGs
            for orientation in PIL.ExifTags.TAGS.keys():
                if PIL.ExifTags.TAGS[orientation] == 'Orientation':
                    break
            e = image._getexif()  # returns None if no EXIF data
            if e is not None:
                #log.info('EXIF data found: %r', e)
                exif = dict(e.items())
                orientation = exif[orientation]
                # print('found, ',orientation)

                if orientation == 3:
                    image = image.transpose(Image.ROTATE_180)
                elif orientation == 6:
                    image = image.transpose(Image.ROTATE_270)
                elif orientation == 8:
                    image = image.rotate(90,expand=True)
    except:
        pass
    return image

#将图片打开保存为pdf,dir2读取文件的目录,output_file_name是输出文件的名,注意需要以pdf结尾
def main(dir2,output_file_name):
    imgDoc = canvas.Canvas(output_file_name)#pagesize=letter
    imgDoc.setPageSize(A4)
    document_width,document_height = A4

    for root2, dirs2, files2 in os.walk(dir2):
        j=0
        #sorted保证按照顺序
        for i2 in sorted(files2,key=lambda x:int(x.split('_')[-1].split('.')[0])):
            obpath2=os.path.join(root2,i2)
            try:
                image_file = PIL.Image.open(obpath2)
                image_file = rotate_img_to_proper(image_file)

                image_width,image_height = image_file.size
                print(image_file.size)
                if not(image_width>0 and image_height>0):
                    raise Exception
                image_aspect = image_height/float(image_width)
                #Determins the demensions of the image in the overview
                print_width  = document_width
                print_height = document_width*image_aspect
                imgDoc.drawImage(ImageReader(image_file),document_width-print_width,
                             document_height-print_height,width=print_width,
                                 height=print_height,preserveAspectRatio=True)
                #inform the reportlab we want a new page
                imgDoc.showPage()
                j +=1
                if j%2000 ==0:#由于不支持巨量图片转pdf,只能分步保存
                    imgDoc.save()
                    output_file_name='../Desktop/未命名文件夹2/relationship'+str(j)+'.pdf'
                    imgDoc = canvas.Canvas(output_file_name)#pagesize=letter
                    imgDoc.setPageSize(A4)
            except Exception as e:
                print('error:',e,obpath2)
    imgDoc.save()
    print('Done')


output_file_name = '../Desktop/未命名文件夹2/relationship.pdf'#pdf文件保存的位置
main(dstpath,output_file_name)
结论:
图片大小为779M,转换完之后3.33G
图片转换完成时间20分钟
图片无法一次性全部转换完

方法二:img2pdf

import img2pdf
filelist=[]
for root2, dirs2, files2 in os.walk(dstpath):
        for i2 in sorted(files2,key=lambda x:int(x.split('_')[-1].split('.')[0])):
            obpath2=os.path.join(root2,i2)
            filelist.append(obpath2)
with open("../Desktop/未命名文件夹2/创业课.pdf", "wb") as f:
    f.write(img2pdf.convert(filelist))
81082300
结论:
图片大小为779M,转换完之后782M
图片转换完成时间<1分钟
图片可以一次性全部转换完
代码少

方法三:fpdf

from fpdf import FPDF
filelist2=[]
for root2, dirs2, files2 in os.walk(dir2):
        for i2 in sorted(files2,key=lambda x:int(x.split('_')[-1].split('.')[0])):
            obpath2=os.path.join(root2,i2)
            filelist2.append(obpath2)
pdf = FPDF()
# imagelist is the list with all image filenames
for image in filelist2:
    pdf.add_page()
    pdf.image(image)
pdf.output("../Desktop/未命名文件夹2/output4.pdf", "F")
''

结论:
没有转换成功,再继续研究下去。因为img2pdf已经足够我用了

启发:
搜索解决方案的时候,中文搜完之后,最好用英文再搜一下,直到高频出现几个关键词,然后再开始尝试。

识别文字

方法一:PyPDF2 主要是英文

import PyPDF2
newfile=open('../Desktop/未命名文件夹2/hello.txt','w')
file=open('../Desktop/未命名文件夹2/OReilly.Hands-On.Machine.Learning.with.Scikit-Learn.and.TensorFlow.2017.3.pdf','rb')
pdfreader=PyPDF2.PdfFileReader(file)
print(pdfreader.getNumPages())
pageobj=pdfreader.getPage(500)
newfile.write(pageobj.extractText())
file.close()
newfile.close()
564





2298

pytesseract模块

#首先安装tesseract: brew install tesseract
#如果需要中文'chi_sim'
#下载中文包https://raw.githubusercontent.com/tesseract-ocr/tessdata/master/chi_sim.traineddata
#将下载的中文包放到/usr/local/Cellar/tesseract/3.05.01/share/tessdata
#再安装pip install pytesseract

import pytesseract
image = PIL.Image.open(filepath)
code = pytesseract.image_to_string(image, lang='chi_sim')
print(code)
u__〕J 日 亡′廿〗 汁炙易雯 o

其实如果能接受自己 “我收钱” 这_点,
人就敞壳多了o 但是这最多是保镖的达
宫。

如果你要 “漂壳” , 那就要做剑侠, 手不
碰钱o 为此他可以矫饰_下o

他要求自己做漂壳事, 但同时也要跟他的
人也做漂壳事o

对自己放低了要求, 对别人调高了期待,
这是不开心的源头o

老郭会觉得徒弟该跟他签那些条件苛刻的
合同。 他觉得北京台_直是朋友, 才会觉
得对方拍他家占用绿地的后院是对不起
结论:识别一般

tesseract直接识别

import os
import subprocess

def image_to_string(img, cleanup=True, plus=''):
    # cleanup为True则识别完成后删除生成的文本文件
    # plus参数为给tesseract的附加高级参数
    subprocess.check_output('tesseract ' + img + ' ' +
                            img + ' ' + plus, shell=True)  # 生成同名txt文件
    text = ''
    with open(img + '.txt', 'r') as f:
        text = f.read().strip()
    if cleanup:
        os.remove(img + '.txt')
    return text
print(image_to_string(s4, False, '-l chi_sim'))
u__〕J 日 亡′廿〗 甘炙髦雯 o

其实如果能接受自己 “我收钱” 这_点,
人就敞壳多了o 但是这最多是保镖的达
宫。

如果你要 “漂壳” , 那就要做剑侠, 手不
碰钱o 为此他可以矫饰_下o

他要求自己做漂壳事, 但同时也要跟他的
人也做漂壳事o

对自己放低了要求, 对别人调高了期待,
这是不开心的源头o

老郭会觉得徒弟该跟他签那些条件苛刻的
合同。 他觉得北京台_直是朋友, 才会觉
得对方拍他家占用绿地的后院是对不起

Search

    欢迎关注我的微信公众号

    闷骚的程序员

    Table of Contents