巧用 Python:將 A3 作業 PDF 輕松轉為 A4 可打印格式

在孩子的學習過程中,我們常常會遇到這樣的困擾:學校老師發的作業是以 A3 格式的 PDF 文件呈現的,然而家里的打印機卻只支持 A4 打印。這時候,要是能有一個簡單的方法把 A3 的 PDF 轉換為 A4 可打印的格式就好了。別擔心,今天我就來分享一下我是如何用 Python 編寫一個實用的轉換程序,輕松解決這個問題的。

我通過編寫 Python 程序,借助幾個常見的 Python 庫,實現了將 A3 格式的 PDF 文件進行分割和重新組合,最終生成適合 A4 打印機打印的 PDF 文件。整個過程只需要簡單的幾個步驟,就可以讓原本無法直接打印的作業變得可以輕松打印出來。

這個程序主要完成了以下幾個關鍵的任務:

  1. PDF 轉圖片:把 A3 格式的 PDF 文件逐頁轉換為圖片,并將這些圖片保存到一個專門的文件夾中。這樣做的好處是方便后續對頁面內容進行處理。
  2. 圖片分割:將生成的圖片從中間左右分割成兩張,模擬將 A3 頁面拆分成兩個 A4 頁面的效果。分割后的圖片會被保存到另一個新的文件夾中。
  3. 圖片合并成 PDF:按照文件名的順序,將分割后的圖片重新合并成一個新的 PDF 文件。這個新的 PDF 文件就是適合 A4 打印機打印的格式了。

下面是具體的代碼實現:

#!/usr/bin/python3
# -*- coding: utf-8 -*-import fitz
import time
import os
import sys
import cv2
import numpy as np
from fpdf import FPDF
from PIL import Image# pip install PyMuPDF
# pip install opencv-python
# pip install fpdf
# pip install Pillow
# 將pdf分割為圖片,并建立一個images1文件夾保存之 傳入要拆解的pdf文件名
def to_image(file_name):dir1 = get_filename_without_ext(file_name) + "_images1"if not os.path.exists(dir1):os.mkdir(dir1)time_start = time.time()doc = fitz.open(file_name)rotate = int(0)zoom_x = 2.0zoom_y = 2.0trans = fitz.Matrix(zoom_x, zoom_y)print("%s開始轉換..." % file_name)pg = 0for page in doc:timep_start = time.time()pg += 1pm = page.get_pixmap(matrix=trans, alpha=False)new_full_name = dir1 + "/" + file_name.split(".")[0]filename1 = "{0:s}{1:0>3d}.jpg".format(new_full_name, pg)pm.save(filename1)timep_end = time.time()print('第 ' + str(pg) + ' 頁生成圖片累計用時:' + str(timep_end - timep_start))time_end = time.time()print('拆解累計用時:' + str(time_end - time_start))# 將images1文件夾中的每個圖片,左右分割為兩張,并新建images2文件夾以保存文件
def cut_img(file_name):dir1 = get_filename_without_ext(file_name) + "_images1"for img in os.listdir(dir1):#print(img)#image = cv2.imread(dir1 + "/" + img)#解決路徑中含有中文的問題image = cv2.imdecode(np.fromfile(dir1 + "/" + img, dtype=np.uint8), cv2.IMREAD_COLOR)if image is None:print("failed to load image")else:x0 = int(image.shape[1]/2)print('x:' + str(x0))dir2 = get_filename_without_ext(file_name) + "_images2"if not os.path.exists(dir2):os.mkdir(dir2)img1 = image[:, 0:x0-100]img2 = image[:, x0-100:]#cv2.imwrite(dir2 + "/" + img[:-4] + '1.jpg', img1)#cv2.imwrite(dir2 + "/" + img[:-4] + '2.jpg', img2)#解決路徑中含有中文的問題cv2.imencode('.jpg', img1)[1].tofile(dir2 + "/" + img[:-4] + '1.jpg')cv2.imencode('.jpg', img2)[1].tofile(dir2 + "/" + img[:-4] + '2.jpg')# 將images2文件夾中的圖片合并成為一個pdf,按照文件名的順序 傳入輸出的pdf文件名
def makePdf(file_name, pdfFileName):dir2 = get_filename_without_ext(file_name) + "_images2"print(dir2)listPages = [dir2 + "/" + imgFileName for imgFileName in os.listdir(dir2)]#print(listPages)cover = Image.open(listPages[0])if cover is None:print('cover is none')else:width, height = cover.sizepdf = FPDF(unit="pt", format = [width, height])for page in listPages:pdf.add_page()pdf.image(page, 0, 0)pdf.output(pdfFileName, "F")# 獲取文件名不帶后綴
def get_filename_without_ext(filepath):filename_with_extension = os.path.basename(filepath)filename, file_extension = os.path.splitext(filename_with_extension)return filenamedef check(question):option = input(">> " + question + " Yes(Y) // No(N): \n>> ")return option == "Y" or option == "yes" or option == "Yes" or option == "y"def fileObj(filePath):print(">> 載入成功, 當前文件對象路徑:" + filePath + "\n")while True:print("### 當前文件對象路徑:" + filePath + " ###\n")option = input("請選擇要執行的操作: 分割(S), 合并(M), 退出當前對象(Q)\n>>")option = option.upper()if option == "S" and check("是否分割"):to_image(filePath)cut_img(filePath)if option == "M" and check("是否合并"):makePdf(filePath, get_filename_without_ext(filePath) + "_result.pdf")if option == "Q":print(">> 處理完畢\n")breakdef main():print("歡迎使用pdf切割程序\n")while True:option = input("請輸入PDF文件路徑:\n>>")if option == 'exit' or option == 'quit' or option == 'q':print(">> 退出!\n")breakelif option == '':print(">> 輸入為空\n")elif option == 'help' or option == '-h':print(">> 請輸入PDF文件路徑:\n")else:if not os.path.exists(option):print(">> 路徑出錯!,請重新輸入PDF路徑:\n")continuefileObj(option)# 執行
if __name__ == "__main__":if len(sys.argv) < 2:main()else:uipath = sys.argv[1]to_image(uipath)cut_img(uipath)makePdf(uipath, get_filename_without_ext(uipath) + "_result.pdf")

通過運行這個程序,你只需要輸入 A3 格式 PDF 文件的路徑,程序就會自動完成分割和合并的操作,最終生成一個適合 A4 打印機打印的 PDF 文件。是不是很方便呢?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/87216.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/87216.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/87216.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Transformer 核心概念轉化為夏日生活類比

以下是把 Transformer 核心概念轉化為「夏日生活類比」&#xff0c;不用看代碼也能秒懂&#xff0c;搭配冰鎮西瓜式記憶法&#xff1a; 一、Transformer 夏日冷飲制作流水線 編碼器&#xff08;Encoder&#xff09;&#xff1a;相當于「食材處理間」 把輸入&#xff08;比如…

【Linux基礎知識系列】第二十九篇-基本的網絡命令(ping, traceroute, netstat)

在Linux系統中&#xff0c;網絡診斷是系統管理員和用戶日常工作中不可或缺的一部分。無論是排查網絡連接問題、檢查網絡延遲&#xff0c;還是監控網絡狀態&#xff0c;掌握一些基本的網絡命令至關重要。本文將詳細介紹ping、traceroute和netstat這三種常用的網絡命令&#xff0…

javaee初階-多線程

1.什么是線程 1.1 進程 要了解線程我們首先需要了解什么是進程&#xff1f; 運行的程序在操作系統中以進程的方式運行&#xff0c;比如說電腦打開不同的軟件&#xff0c;軟件就是不同的進程 1.1.1進程的組織方式 通過雙向鏈表 創建進程就是在雙向鏈表上添加PCB 銷毀一個進…

N數據分析pandas基礎.py

前言&#xff1a;在數據分析領域&#xff0c;Python 的 Pandas 庫堪稱得力助手。它不僅擁有高效的數據處理能力&#xff0c;還能與 NumPy 完美配合——后者強大的數值計算功能為 Pandas 提供了堅實的技術基礎。 目錄 Pandas數據分析實戰&#xff1a;解鎖數據處理的高效之道 數…

衛星通信鏈路預算之二:帶寬和功帶平衡

在上一個章節衛星通信鏈路預算之一&#xff1a;信噪比分配 中&#xff0c;我們介紹了衛星通信鏈路中最核心的概念&#xff1a;信噪比分配&#xff0c;并給出了衛星通信鏈路總信噪比的計算公式。 本篇文章&#xff0c;我們將介紹衛星通信鏈路中的另外一個基本概念&#xff1a;帶…

QGIS新手教程5:圖層屬性查詢與表達式篩選技巧

? QGIS新手教程5&#xff1a;圖層屬性查詢與表達式篩選技巧 字段篩選、表達式構建器、選擇集操作一步到位&#xff01; 目錄 ? QGIS新手教程5&#xff1a;圖層屬性查詢與表達式篩選技巧&#x1f4c1; 一、示例數據準備&#xff08;繼續使用第四篇中的示例&#xff09;&#…

用 el-dialog 做出彈出框是圖片

今天項目上用到個功能是點擊按鈕彈出一個 modal&#xff0c;有遮罩層而且在上面顯示圖片。 其實就是 el-dialog 的功能&#xff0c;但是 el-dialog 彈出后&#xff0c;有標簽關閉按鈕還有背景。 解決辦法&#xff1a;el-dialog 的 width 設為 0 就可以了。 <template>…

Gartner《Decision Point for Selecting the Right APIMediation Technology》學習心得

一、API 中介技術概述 背景&#xff0c;API 中介技術變得多樣化&#xff0c;應用與集成架構師需要借助決策框架&#xff0c;從企業級 API 網關、輕量級網關、入口網關以及服務網格中挑選出適合多粒度服務和 API 的中介技術。 隨著無服務器架構與容器管理系統的興起&#xff0…

快速 SystemC 之旅(一)

快速 SystemC 之旅&#xff08;一&#xff09; 一、前言背景二、實驗環境1. 安裝步驟2. 驗證安裝 三、RTL 級硬件描述1. 初看模塊2. 二輸入與非門 一、前言背景 因項目需求&#xff0c;近期開始開展電子系統級設計&#xff08;ESL&#xff09;進行事務級建模&#xff08;TLM&a…

解決 Golang 下載golang.org/x包失敗方案

在 Golang 開發過程中&#xff0c;不少開發者都遇到過這樣的困擾&#xff1a;當試圖下載golang.org相關包時&#xff0c;會出現訪問失敗的情況&#xff0c;尤其是golang.org/x系列包&#xff0c;作為眾多第三方庫依賴的核心組件&#xff0c;其無法正常下載會嚴重影響項目的開發…

CppCon 2016 學習:BUILDING A MODERN C++ FORGE FOR COMPUTE AND GRAPHICS

你提供的這段文字是關于 設計一個精簡但足夠的 C 框架來驅動 Vulkan 的目標陳述&#xff0c;屬于項目文檔或演講的第一部分 “Goals”。我們可以把它逐項拆解并深入理解&#xff1a; PART (I – I): GOALS&#xff08;目標&#xff09; 總體目標&#xff1a; 構建一個最小但足…

# AI武裝大腦:技術管理者如何用人工智能重構認知與決策系統

作為一位經歷了15年技術管理實戰的老兵&#xff0c;我見過太多項目因為決策失誤、認知局限而陷入泥潭。直到我開始系統性地用AI武裝大腦&#xff0c;才真正找到了突破技術管理瓶頸的利器。今天&#xff0c;我要分享的不是那些泛泛而談的AI概念&#xff0c;而是如何用AI真正提升…

【Linux】UDP與TCP協議

目錄 UDP協議 1.1通信流程 1.2函數 socket bind sendto recvfrom close 1.3實現udp通信 TCP協議 1.1TCP頭部結構 1.2通信流程 三次握手 正式通信 四次揮手 1.3協議特性 面向字節流 可靠傳輸 序列號和確認號 重傳機制 流量控制和擁塞控制 1.4常用函數 s…

gbase8s之MyBatis批量update問題

源代碼 <update id"updateDynamicTableData"><foreach collection"mapList" item"map" separator";">UPDATE ${tableName} SET<foreach collection"map" item"value" index"key" separ…

博圖SCL中WHILE語句的使用詳解及案例

在西門子TIA Portal的SCL&#xff08;結構化控制語言&#xff09;編程中&#xff0c;WHILE循環是處理條件迭代任務的核心工具。它根據布爾表達式動態控制循環執行&#xff0c;適用于不確定循環次數的場景。下面從語法、執行流程、注意事項到實際案例全面解析。 一、WHILE循環基…

簡單聊聊JVM中的幾種垃圾收集算法

3.4、分代收集算法 分代收集算法&#xff0c;可以看成以上內容的延伸。它的實現思路是根據對象的生命周期的不同&#xff0c;將內存劃分為幾塊&#xff0c;比如把堆空間劃分為新生代和老年代&#xff0c;然后根據各塊的特點采用最適當的收集算法。 在新生代中&#xff0c;存在…

依賴已導入,已下載,無法使用問題

明明已經導入依賴&#xff0c;卻無法使用相關注解 于是&#xff0c;我使用 mvn dependency:tree -Dverbose 來查看是否有依賴沖突 [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal on project agileboot…

答題考試系統小程序ThinkPHP+UniApp

ThinkPHPUniapp開發的小程序答題考試系統&#xff0c;支持多種試題類型、多種試題難度、練題、考試、補考模式&#xff0c;提供全部前后臺無加密源代碼&#xff0c;支持私有化部署. 更新日志 V1.7.1修復一些問題 解決考場成績列表重復問題&#xff1b; 解決后臺材料題選擇子…

DHCP服務管理

目錄 DHCP協議 DHCP的優勢 DHCP的分配方式 應用場景 注意 工作流程 何時更新租約 當客戶端重啟后 客戶端類型 DCHP安裝與配置 網絡規劃&#xff1a; 配置 DHCP 作用域 啟動 DHCP 服務 配置路由器 配置路由器網卡 IP 開啟 IP 轉發&#xff08;確保跨網段通信&…

12.UDP客戶端

準備工作 硬件準備&#xff1a;確保你的STM32板子已經正確連接了DP83848網絡芯片。 軟件設置&#xff1a; 安裝好STM32CubeMX用于配置工程。 選擇合適的STM32 HAL庫版本。 如果可能的話&#xff0c;安裝LwIP庫支持TCP/IP協議棧。 步驟 1. 使用STM32CubeMX配置項目 打開…