【Python精彩案例】随拍文档转PDF扫描版
在需要掃描文件時(shí),附近沒有打印店怎么辦?今天分享如何使用Python實(shí)現(xiàn)文檔轉(zhuǎn)pdf掃描。
老規(guī)矩,在進(jìn)入正文之前,咱們先看看最終效果:
1 文檔矯正
如下圖所示,手持相機(jī)拍攝出來的圖片一般都是不標(biāo)準(zhǔn)的矩形。
需要通過技術(shù)手段將其矯正為標(biāo)準(zhǔn)的矩形,通過透視投影變換可以將任意四邊區(qū)域內(nèi)容投影到另一個(gè)四邊形區(qū)域。
首先確定需要變換的4個(gè)點(diǎn),然后確定投影后的4個(gè)點(diǎn),可以得到一個(gè)變換矩陣,最后通過調(diào)用opencv的warpPerspective即可實(shí)現(xiàn)矯正。
投影后的四個(gè)點(diǎn)其實(shí)只需通過寬高即可確定,因?yàn)?個(gè)點(diǎn)位置為(0,0)、(w,0)、(w,h)、(0,h)。那么如何確定輸入的4個(gè)點(diǎn)呢?這里簡(jiǎn)單寫了個(gè)圖片顯示:
from matplotlib import pyplot as plt def show_img(path):img = plt.imread(path)plt.imshow(img)plt.show()鼠標(biāo)移動(dòng)到圖像各個(gè)位置時(shí),右下角會(huì)顯示當(dāng)前點(diǎn)坐標(biāo)。如下圖所示:
找到左上、右上、右下、左下四個(gè)點(diǎn)位置分別為[400, 703], [2384, 656], [2635, 3280], [294, 3357]。可以根據(jù)實(shí)際的文檔寬高設(shè)置投影變換后的尺寸,這里設(shè)置為寬度為515, 高度為663。
src, dst, src_pts, dw, dh分別表示輸入圖路徑、矯正后圖路徑、原始四個(gè)點(diǎn),目標(biāo)寬高。將各個(gè)參數(shù)傳入如上函數(shù),得到矯正后圖如下:
2 創(chuàng)建PDF文件并添加圖片
有了矯正后的圖片,接下來任務(wù)是創(chuàng)建PDF文件并將圖片插入到PDF文件中。
2.1 創(chuàng)建PDF
首先通過pip install reportlab安裝reportlab庫(kù)。接下來創(chuàng)建PDF:
from reportlab.lib.pagesizes import A4 from reportlab.pdfgen import canvasdef create_pdf(filename, width_height=A4):cvs = canvas.Canvas(filename, pagesize=width_height)return cvsreportlab.pdfgen生成PDF文件,將PDF看成是一個(gè)畫板Canvas。Canvas可以指定頁(yè)面的寬高。但需要注意,這里的寬高是以點(diǎn)為單位。關(guān)于點(diǎn)的單位換算如下:
- 1 inch = 72 點(diǎn)
- 1 inch = 25.4 mm
因此,我們可以輕易得到毫米(mm)轉(zhuǎn)點(diǎn)單位換算:
- 1 mm = 72/25.4 點(diǎn)
對(duì)于A4紙張,其寬高分別為210 mm和297 mm。當(dāng)然了,reportlab已經(jīng)提供了常用的尺寸如:
from reportlab.lib.pagesizes import A42.2 插入圖片
調(diào)用Canvas的drawImage函數(shù)實(shí)現(xiàn)圖像插入。并最后通過save函數(shù)保存pdf文件
def insert_imgs(cvs, img_path, rect):x, y, w, h = rectcvs.drawImage(img_path, x, y, width=w, height=h)cvs.save()2.3 其他功能
不僅僅是插入圖片,對(duì)于插入文字,reportlab也是輕松可以實(shí)現(xiàn):
cvs.drawString(x, y, "hello world")創(chuàng)建新一頁(yè):
cvs.showPage()調(diào)用showPage函數(shù)后,如果后面還有新的添加元素,則會(huì)開啟新的一頁(yè),并添加到新的一頁(yè)上。更多細(xì)節(jié),可以參考https://www.reportlab.com/docs/reportlab-userguide.pdf
完整代碼關(guān)注【Python學(xué)習(xí)實(shí)戰(zhàn)】公眾號(hào),回復(fù)2202獲取完整的代碼。
歡迎關(guān)注我【Python學(xué)習(xí)實(shí)戰(zhàn)】,每天學(xué)習(xí)一點(diǎn)點(diǎn),每天進(jìn)步一點(diǎn)點(diǎn)。
總結(jié)
以上是生活随笔為你收集整理的【Python精彩案例】随拍文档转PDF扫描版的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GaussDB Hash表分布列选择原则
- 下一篇: 怎样用python爬虫付费文档_pyth