Python chuyển đổi nhiều png sang pdf

Bài viết này sẽ hướng dẫn bạn một kỹ thuật chuyển đổi tệp PDF sang tệp hình ảnh PNG. Vấn đề mà bài viết này nhằm giải quyết là một người không muốn lưu trữ bất kỳ dữ liệu nào trên hệ thống của mình trong quá trình chuyển đổi

Hệ thống mà chuyển đổi xảy ra không lưu trữ bất cứ thứ gì. Điều này rất quan trọng đối với nhà phát triển vì ví dụ như trong API nằm trong máy chủ, tài nguyên lưu trữ/phần cứng máy chủ cần được sử dụng hiệu quả. Nó không nên được sử dụng để kết xuất dữ liệu vô ích. Vì mã không lưu trữ bất cứ thứ gì trên hệ thống gốc nên không có bộ nhớ nào được sử dụng trong khi đạt được chuyển đổi

Sau khi dành nhiều thời gian trên internet và sau đó kiểm tra mã của mình, tôi đã tìm ra giải pháp

Bộ luật và giải thích của nó
  1. Lưu trữ tệp trong một biến trong python. Tệp của tôi đến từ mạng, do đó tôi sử dụng yêu cầu để truy cập tệp đã tải lên
file = request.files["file"]

2. Trích xuất tên tệp từ tệp. Tài liệu warkzeug yêu cầu rõ ràng gọi hàm bảo mật trên

file.filename = secure_filename(file.filename)
9 để nhận phiên bản bảo mật của tên tệp

file.filename = secure_filename(file.filename)

3. Nhập gói

from pdf2image import convert_from_bytespages = convert_from_bytes(file.read())
0 và chuyển đổi byte pdf thành byte giá trị RGB bằng cách gọi hàm do gói
from pdf2image import convert_from_bytespages = convert_from_bytes(file.read())
0 cung cấp. Đây là một chuyển đổi byte sang byte. Cho đến nay, chúng tôi không nhận được thực tế. hình ảnh định dạng png

from pdf2image import convert_from_bytespages = convert_from_bytes(file.read())

4. Tạo một đối tượng trong bộ nhớ đệm và lưu tệp dưới dạng. png trong bộ đệm trong bộ nhớ

Chúng ta cần xác định bộ đệm trong bộ nhớ có thể lưu trữ byte. Cái này giống như biến python lưu trữ dữ liệu nhưng ở đây kiểu dữ liệu là ‘byte’. Bạn không thể lưu trữ nó bình thường bằng cách chỉ xác định một biến

Một cách khác để lưu trữ trong bộ nhớ là ghi các byte vào một tệp, nhưng tệp đó sẽ được lưu trên máy tính của bạn. Hãy tưởng tượng nếu API này được gọi 100 lần và các tệp 5 MB được cung cấp mỗi lần, bạn sẽ lãng phí 500Mb dung lượng ổ đĩa

for page in pages:   in_mem_file = io.BytesIO()   page.save(in_mem_file , format = "png")   in_mem_file.seek(0)break

from pdf2image import convert_from_bytespages = convert_from_bytes(file.read())
2 chuyển đổi các byte trong trang thành các byte có định dạng png và lưu các byte đó trong biến in-mem.
from pdf2image import convert_from_bytespages = convert_from_bytes(file.read())
3 định vị lại con trỏ byte để trỏ lại đầu mảng

Khi

file.filename = secure_filename(file.filename)
0 được gọi , con trỏ điền vào
file.filename = secure_filename(file.filename)
1 đã đạt đến cuối độ dài của nó, do đó khi chúng ta sẽ đọc nó; . Nếu chúng tôi không định vị lại, sẽ không có byte nào được đọc. Vì một con trỏ duy nhất thực hiện cả thao tác ghi và đọc nên chúng ta cần quản lý nó theo cách thủ công

Giờ đây, bạn có thể gửi lại các byte hình ảnh png trong mạng đến một nơi khác hoặc bạn có thể lưu trữ nó trên hệ thống của mình bằng cách sử dụng thêm một vài dòng mã

Vòng lặp for được sử dụng vì đối tượng pages là một đối tượng có thể lặp lại. Điều này có nghĩa là nếu pdf của bạn có nhiều trang thì tất cả chúng sẽ được lưu trữ trong các trang. Các trang hoạt động giống như một danh sách trong đó mỗi chỉ mục chứa một trang

Tôi đã sử dụng ngắt để dừng chuyển đổi khi hoàn thành 1 trang. Bạn có thể xóa câu lệnh break, nhưng hãy nhớ xử lý

file.filename = secure_filename(file.filename)
1 và ngăn vòng lặp for ghi đè lên nó

Gần đây tôi đang làm việc trên một dự án RPA yêu cầu xử lý nhiều tệp PDF. Có bốn nhiệm vụ chủ yếu liên quan

  1. Kết hợp nhiều tệp PDF thành một tệp duy nhất
  2. Tách một tệp PDF nhiều trang thành nhiều tệp PDF một trang
  3. Chuyển đổi tệp PDF (một trang hoặc nhiều trang) thành tệp PNG
  4. Sử dụng OCR để chuyển đổi tệp PNG thành văn bản

Mục đích cuối cùng là đổi tên các tệp PDF được quét dựa trên nội dung của chúng. Tôi sẽ thực hiện các bước để giải quyết 3 nhiệm vụ đầu tiên ở đây, đối với phần OCR, có nhiều tùy chọn có sẵn nhưng lưu ý, nhiều trong số chúng không hoạt động tốt với các ký tự tiếng Trung, ví dụ như Tesseract, ngay cả với

Nếu không có Python, chúng tôi phải sử dụng Adobe Acrobat Professional để kết hợp và chia nhỏ các tệp PDF hoặc tìm một số dịch vụ trực tuyến có nguy cơ mất thông tin bảo mật. Nhưng chúng ta có thể dễ dàng thực hiện điều này bằng Python với chi phí bằng không và bảo mật tối đa cộng với hiệu quả

Tìm gói phù hợp

Ban đầu, tôi đã thử gói

from pdf2image import convert_from_bytespages = convert_from_bytes(file.read())
4 mà tôi dùng để điền vào biểu mẫu PDF, tuy nhiên gói này không phù hợp để đọc tài liệu PDF được quét. Sau khi tìm kiếm, gói tôi tìm thấy là
from pdf2image import convert_from_bytespages = convert_from_bytes(file.read())
5 (https. //github. com/pymupdf/PyMuPDF), nó phục vụ mọi mục đích tôi có ở đây, bao gồm kết hợp, chia nhỏ tệp PDF và chuyển đổi từng trang thành tệp PNG

Để cài đặt

from pdf2image import convert_from_bytespages = convert_from_bytes(file.read())
5 , tất cả những gì bạn cần làm là
from pdf2image import convert_from_bytespages = convert_from_bytes(file.read())
7 , tuy nhiên bạn thực sự cần phải
from pdf2image import convert_from_bytespages = convert_from_bytes(file.read())
8 để sử dụng nó, đây là một điều kỳ lạ vì bạn cần phải nhớ hai tên gói khác nhau. Thủ thuật tôi đã sử dụng là để lại nhận xét sau dòng nhập

import fitz # pip install pymupdf
Kết hợp nhiều tệp PDF

Để kết hợp nhiều tệp PDF, trước tiên bạn cần tạo một tệp PDF trống bằng cách sử dụng

with fitz.open() as doc:
for pdf_file in pdf_files:
doc.insert_pdf(fitz.open(pdf_file), from_page=0, to_page=-1, rotate=-1, show_progress=True, final=True)
doc.save(save_as)
0, sau đó lưu nó sau khi chèn từng tệp PDF vào tệp mới

Giả sử bạn có tất cả các tệp PDF với đường dẫn đầy đủ được lưu trữ trong danh sách

with fitz.open() as doc:
for pdf_file in pdf_files:
doc.insert_pdf(fitz.open(pdf_file), from_page=0, to_page=-1, rotate=-1, show_progress=True, final=True)
doc.save(save_as)
1, 3 dòng mã sau đạt được mục đích trên

with fitz.open() as doc:
for pdf_file in pdf_files:
doc.insert_pdf(fitz.open(pdf_file), from_page=0, to_page=-1, rotate=-1, show_progress=True, final=True)
doc.save(save_as)
Chia một tệp PDF thành nhiều trang

Để tách một tệp PDF nhiều trang, ý tưởng gần giống như bài tập trước, bạn chỉ cần mở một tệp PDF hiện có và chèn vào một loạt các tệp mới theo từng trang

9 dòng mã sau đạt được mục đích trên

file.filename = secure_filename(file.filename)
1

Dòng thứ 2 và thứ 4 tính toán tổng số trang và nối thêm

with fitz.open() as doc:
for pdf_file in pdf_files:
doc.insert_pdf(fitz.open(pdf_file), from_page=0, to_page=-1, rotate=-1, show_progress=True, final=True)
doc.save(save_as)
2 đến
with fitz.open() as doc:
for pdf_file in pdf_files:
doc.insert_pdf(fitz.open(pdf_file), from_page=0, to_page=-1, rotate=-1, show_progress=True, final=True)
doc.save(save_as)
3 vào tên tệp nếu có ít hơn 10 trang hoặc
with fitz.open() as doc:
for pdf_file in pdf_files:
doc.insert_pdf(fitz.open(pdf_file), from_page=0, to_page=-1, rotate=-1, show_progress=True, final=True)
doc.save(save_as)
4 đến
with fitz.open() as doc:
for pdf_file in pdf_files:
doc.insert_pdf(fitz.open(pdf_file), from_page=0, to_page=-1, rotate=-1, show_progress=True, final=True)
doc.save(save_as)
5 nếu có từ 10 đến 99 trang, v.v. Đó là một cách thực hành tốt hơn nếu bạn muốn giữ tên tệp theo thứ tự bất cứ khi nào bạn cần truy cập chúng theo cách thủ công hoặc bằng mã

Chuyển đổi tệp PDF sang (các) tệp PNG

Với vấn đề truy cập từng trang của tệp PDF đã được giải quyết ở trên, chúng ta chỉ cần sử dụng đoạn mã sau để chuyển đổi một trang thành tệp PNG

file.filename = secure_filename(file.filename)
6

Kết hợp với bài tập liệt kê trang trước, ta có đoạn mã hoàn chỉnh sau

file.filename = secure_filename(file.filename)
7

Dòng mã thứ 4 đến thứ 8 tạo hậu tố cho tên tệp PNG nếu có nhiều trang, nếu không thì chỉ tên tệp PDF gốc có phần mở rộng

with fitz.open() as doc:
for pdf_file in pdf_files:
doc.insert_pdf(fitz.open(pdf_file), from_page=0, to_page=-1, rotate=-1, show_progress=True, final=True)
doc.save(save_as)
6

Phòng cải tiến

Bạn có thể bọc các mã trên thành các hàm hoặc thậm chí là một lớp để dễ truy cập chúng hơn

Và có những lĩnh vực khác mà bạn có thể khám phá, chẳng hạn như bạn có thể trích xuất TOC, chú thích, v.v. từ PDF bằng gói

from pdf2image import convert_from_bytespages = convert_from_bytes(file.read())
5