convert-stream 1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of convert-stream might be problematic. Click here for more details.
- convert_stream/__init__.py +19 -0
- convert_stream/__main__.py +29 -0
- convert_stream/_version.py +7 -0
- convert_stream/convert.py +300 -0
- convert_stream/imagelib.py +493 -0
- convert_stream/library.py +5 -0
- convert_stream/models/__init__.py +10 -0
- convert_stream/models/m_imgelib.py +107 -0
- convert_stream/models/m_pdf_convert.py +171 -0
- convert_stream/models/m_pdf_document.py +139 -0
- convert_stream/models/m_pdf_page.py +88 -0
- convert_stream/models/m_text.py +480 -0
- convert_stream/pdf_convert.py +282 -0
- convert_stream/pdf_document.py +534 -0
- convert_stream/pdf_page.py +251 -0
- convert_stream/text.py +8 -0
- convert_stream-1.1.dist-info/METADATA +45 -0
- convert_stream-1.1.dist-info/RECORD +20 -0
- convert_stream-1.1.dist-info/WHEEL +5 -0
- convert_stream-1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from typing import List, Dict
|
|
5
|
+
from io import BytesIO
|
|
6
|
+
from PIL import Image
|
|
7
|
+
from reportlab.pdfgen import canvas
|
|
8
|
+
from reportlab.pdfgen.canvas import Canvas
|
|
9
|
+
from reportlab.lib.pagesizes import letter
|
|
10
|
+
from reportlab.lib.utils import ImageReader
|
|
11
|
+
|
|
12
|
+
from soup_files import File
|
|
13
|
+
from convertlib.imagelib import ImageObject, LibraryImage
|
|
14
|
+
from convertlib.models import ABCConvertPdf, ABCImageConvertPdf, LibraryPDF
|
|
15
|
+
from convertlib.pdf_page import PageDocumentPdf
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
from fitz import Matrix, Pixmap, Document, Page
|
|
19
|
+
except:
|
|
20
|
+
from pymupdf import Matrix, Pixmap, Document, Page
|
|
21
|
+
|
|
22
|
+
#======================================================================#
|
|
23
|
+
# Converter PDFs em Imagens
|
|
24
|
+
#======================================================================#
|
|
25
|
+
class ImplementPdfToImageFitz(ABCConvertPdf):
|
|
26
|
+
"""
|
|
27
|
+
Implementação para converter PDFs em Imagens (ImageObject) com o fitz.
|
|
28
|
+
"""
|
|
29
|
+
def __init__(self, library_image:LibraryImage=LibraryImage.OPENCV, *, dpi:int=200):
|
|
30
|
+
super().__init__()
|
|
31
|
+
self.library_image:LibraryImage = library_image
|
|
32
|
+
self.dpi:int = dpi
|
|
33
|
+
|
|
34
|
+
def from_page_bytes(self, page_bytes:bytes) -> ImageObject:
|
|
35
|
+
"""
|
|
36
|
+
Recebe uma página PDF e converte os bytes da página PDF em ImagemObject
|
|
37
|
+
"""
|
|
38
|
+
if not isinstance(page_bytes, bytes):
|
|
39
|
+
raise ValueError(f'{__class__.__name__}\nUse: bytes, não {type(page_bytes)}')
|
|
40
|
+
|
|
41
|
+
page_pdf:PageDocumentPdf = PageDocumentPdf.create_from_page_bytes(page_bytes, library=LibraryPDF.FITZ)
|
|
42
|
+
pix:Pixmap = page_pdf.page.page.get_pixmap()
|
|
43
|
+
return ImageObject.create_from_bytes(pix.tobytes(), library=self.library_image)
|
|
44
|
+
|
|
45
|
+
def from_page_pdf(self, page:PageDocumentPdf) -> ImageObject:
|
|
46
|
+
if page.current_library == LibraryPDF.FITZ:
|
|
47
|
+
return self.__from_page_fitz(page.page.page)
|
|
48
|
+
return self.from_page_bytes(page.to_bytes())
|
|
49
|
+
|
|
50
|
+
def __from_page_fitz(self, page_fitz:Page) -> ImageObject:
|
|
51
|
+
"""Converte uma página PDF em imagem."""
|
|
52
|
+
if not isinstance(page_fitz, Page):
|
|
53
|
+
raise ValueError(f'{__class__.__name__}Use: fitz.Page(), não {type(page_fitz)}')
|
|
54
|
+
pix:Pixmap = page_fitz.get_pixmap()
|
|
55
|
+
return ImageObject.create_from_bytes(pix.tobytes(), library=self.library_image)
|
|
56
|
+
|
|
57
|
+
def inner_images(self, page_bytes) -> List[ImageObject]:
|
|
58
|
+
images_obj:List[ImageObject] = []
|
|
59
|
+
doc = Document(stream=page_bytes, filetype="pdf")
|
|
60
|
+
page:Page = doc[0]
|
|
61
|
+
# Extrair imagens embutidas na página
|
|
62
|
+
images_list = page.get_images(full=True)
|
|
63
|
+
for img in images_list:
|
|
64
|
+
try:
|
|
65
|
+
xref = img[0] # Referência do objeto da imagem
|
|
66
|
+
base_image = doc.extract_image(xref) # Extrair imagem
|
|
67
|
+
image_bytes = base_image["image"] # Bytes da imagem
|
|
68
|
+
image_ext = base_image["ext"] # Extensão (jpg, png, etc.)
|
|
69
|
+
except Exception as e:
|
|
70
|
+
print(e)
|
|
71
|
+
else:
|
|
72
|
+
img = ImageObject.create_from_bytes(image_bytes, library=self.library_image)
|
|
73
|
+
images_obj.append(img)
|
|
74
|
+
return images_obj
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class ConvertPdfToImage(ABCConvertPdf):
|
|
78
|
+
def __init__(self, *, library_pdf=LibraryPDF.FITZ, library_image=LibraryImage.OPENCV, dpi:int=200):
|
|
79
|
+
super().__init__()
|
|
80
|
+
self.library_pdf:LibraryPDF = library_pdf
|
|
81
|
+
if self.library_pdf == LibraryPDF.FITZ:
|
|
82
|
+
self.convert_pdf_to_images = ImplementPdfToImageFitz(library_image, dpi=dpi)
|
|
83
|
+
elif self.library_pdf == LibraryPDF.PYPDF:
|
|
84
|
+
raise NotImplementedError(f'{__class__.__name__}\nFuncionalidade não implementada para PYPDF2')
|
|
85
|
+
elif self.library_pdf == LibraryPDF.CANVAS:
|
|
86
|
+
raise NotImplementedError(f'{__class__.__name__}\nFuncionalidade não implementada para CANVAS')
|
|
87
|
+
else:
|
|
88
|
+
raise NotImplementedError(f'{__class__.__name__}\nLibraryPDF inválida: {type(self.library_pdf)}')
|
|
89
|
+
|
|
90
|
+
def from_page_bytes(self, page_bytes:bytes) -> ImageObject:
|
|
91
|
+
print(f'[+] {__class__.__name__}() Convertendo bytes pdf em imagem, aguarde')
|
|
92
|
+
return self.convert_pdf_to_images.from_page_bytes(page_bytes)
|
|
93
|
+
|
|
94
|
+
def from_page_pdf(self, page:PageDocumentPdf) -> ImageObject:
|
|
95
|
+
print(f'[+] {__class__.__name__}() Convertendo página pdf em imagem, aguarde')
|
|
96
|
+
return self.convert_pdf_to_images.from_page_pdf(page)
|
|
97
|
+
|
|
98
|
+
def inner_images(self, page_bytes) -> List[ImageObject]:
|
|
99
|
+
print(f'[+] {__class__.__name__}() Extraindo imagem de página PDF, aguarde')
|
|
100
|
+
return self.convert_pdf_to_images.inner_images(page_bytes)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
#########################################################################
|
|
104
|
+
# Converter IMAGEM para Arquivo ou página PDF.
|
|
105
|
+
#########################################################################
|
|
106
|
+
|
|
107
|
+
class ImplementImageConvertPdfFitz(ABCImageConvertPdf):
|
|
108
|
+
def __init__(self, library_image):
|
|
109
|
+
super().__init__(library_image)
|
|
110
|
+
self._library_pdf = LibraryPDF.FITZ
|
|
111
|
+
|
|
112
|
+
def from_image_file(self, file:File) -> PageDocumentPdf:
|
|
113
|
+
# https://pymupdf.readthedocs.io/en/latest/recipes-images.html
|
|
114
|
+
|
|
115
|
+
doc = Document()
|
|
116
|
+
img:Document = Document(file.absolute()) # open pic as document
|
|
117
|
+
rect = img[0].rect # pic dimension
|
|
118
|
+
pdfbytes = img.convert_to_pdf() # make a PDF stream
|
|
119
|
+
img.close() # no longer needed
|
|
120
|
+
imgPDF = Document("pdf", pdfbytes) # open stream as PDF
|
|
121
|
+
|
|
122
|
+
page = doc.new_page(
|
|
123
|
+
width = rect.width, # new page with ...
|
|
124
|
+
height = rect.height # pic dimension
|
|
125
|
+
)
|
|
126
|
+
page.show_pdf_page(rect, imgPDF, 0) # image fills the page
|
|
127
|
+
return PageDocumentPdf.create_from_page_fitz(page)
|
|
128
|
+
|
|
129
|
+
def from_image(self, img:ImageObject) -> PageDocumentPdf:
|
|
130
|
+
return self.from_image_bytes(img.to_bytes())
|
|
131
|
+
|
|
132
|
+
def from_image_bytes(self, image_bytes:bytes) -> PageDocumentPdf:
|
|
133
|
+
doc:Document = Document()
|
|
134
|
+
|
|
135
|
+
# Criar um Pixmap diretamente dos bytes da imagem
|
|
136
|
+
pix = Pixmap(BytesIO(image_bytes))
|
|
137
|
+
|
|
138
|
+
# Criar uma nova página do tamanho da imagem
|
|
139
|
+
page = doc.new_page(width=pix.width, height=pix.height)
|
|
140
|
+
|
|
141
|
+
# Inserir a imagem na página
|
|
142
|
+
page.insert_image(page.rect, pixmap=pix)
|
|
143
|
+
return PageDocumentPdf.create_from_page_fitz(page)
|
|
144
|
+
|
|
145
|
+
# Implementação para converter imagem em PDF usando CANVAS.
|
|
146
|
+
class ImplementImageConvertPdfCanvas(ABCImageConvertPdf):
|
|
147
|
+
"""
|
|
148
|
+
Implementação para converter uma imagem em página PDF (canvas).
|
|
149
|
+
"""
|
|
150
|
+
def __init__(self, library_image):
|
|
151
|
+
super().__init__(library_image)
|
|
152
|
+
self._library_pdf = LibraryPDF.FITZ
|
|
153
|
+
|
|
154
|
+
def from_image(self, img:ImageObject) -> PageDocumentPdf:
|
|
155
|
+
# Cria um buffer de memória para o PDF
|
|
156
|
+
buffer_pdf = BytesIO()
|
|
157
|
+
|
|
158
|
+
# Cria o canvas associado ao buffer
|
|
159
|
+
c:Canvas = canvas.Canvas(buffer_pdf, pagesize=letter)
|
|
160
|
+
# Adicionar a imagem.
|
|
161
|
+
c.drawImage(
|
|
162
|
+
ImageReader(img.to_image_pil()),
|
|
163
|
+
0,
|
|
164
|
+
0,
|
|
165
|
+
width=letter[0],
|
|
166
|
+
height=letter[1],
|
|
167
|
+
preserveAspectRatio=True,
|
|
168
|
+
anchor='c'
|
|
169
|
+
)
|
|
170
|
+
c.showPage()
|
|
171
|
+
|
|
172
|
+
# Finaliza o PDF
|
|
173
|
+
c.save()
|
|
174
|
+
|
|
175
|
+
# Move o ponteiro do buffer para o início
|
|
176
|
+
buffer_pdf.seek(0)
|
|
177
|
+
|
|
178
|
+
# Obtém os bytes do PDF
|
|
179
|
+
pdf_bytes = buffer_pdf.getvalue()
|
|
180
|
+
|
|
181
|
+
# Fecha o buffer (opcional, mas recomendado)
|
|
182
|
+
buffer_pdf.close()
|
|
183
|
+
|
|
184
|
+
# Gerar a página PDF
|
|
185
|
+
return PageDocumentPdf.create_from_page_bytes(pdf_bytes, library=self._library_pdf)
|
|
186
|
+
|
|
187
|
+
def from_image_file(self, file:File) -> PageDocumentPdf:
|
|
188
|
+
"""
|
|
189
|
+
Converter um arquivo de imagem em páginas PDF
|
|
190
|
+
"""
|
|
191
|
+
img = ImageObject.create_from_file(file, library=self.library_image)
|
|
192
|
+
return self.from_image(img)
|
|
193
|
+
|
|
194
|
+
def from_image_bytes(self, img_bytes:bytes) -> PageDocumentPdf:
|
|
195
|
+
return self.from_image(
|
|
196
|
+
ImageObject.create_from_bytes(img_bytes, library=self.library_image)
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
# Implementação para converter imagem em PDF usando PIL.
|
|
200
|
+
class ImplementImageConvertToPdfPIL(ABCImageConvertPdf):
|
|
201
|
+
"""
|
|
202
|
+
Implementação para converter uma imagem em página PDF (PIL).
|
|
203
|
+
"""
|
|
204
|
+
def __init__(self, library_image):
|
|
205
|
+
super().__init__(library_image)
|
|
206
|
+
self._library_pdf:LibraryPDF = LibraryPDF.FITZ
|
|
207
|
+
|
|
208
|
+
def from_image(self, img:ImageObject) -> PageDocumentPdf:
|
|
209
|
+
img_pil = img.to_image_pil()
|
|
210
|
+
buff = BytesIO()
|
|
211
|
+
# Converter e salvar como PDF
|
|
212
|
+
img_pil.save(buff, "PDF")
|
|
213
|
+
pdf_bytes:bytes = buff.getvalue()
|
|
214
|
+
buff.close()
|
|
215
|
+
return PageDocumentPdf.create_from_page_bytes(pdf_bytes, library=self._library_pdf)
|
|
216
|
+
|
|
217
|
+
def from_image_file(self, file:File) -> PageDocumentPdf:
|
|
218
|
+
"""
|
|
219
|
+
Converter um arquivo de imagem em páginas PDF
|
|
220
|
+
"""
|
|
221
|
+
# Carregar a imagem
|
|
222
|
+
imagem:Image.Image = Image.open(file.absolute())
|
|
223
|
+
buff = BytesIO()
|
|
224
|
+
# Converter e salvar como PDF
|
|
225
|
+
imagem.save(buff, "PDF")
|
|
226
|
+
pdf_bytes:bytes = buff.getvalue()
|
|
227
|
+
buff.close()
|
|
228
|
+
return PageDocumentPdf.create_from_page_bytes(pdf_bytes, library=self._library_pdf)
|
|
229
|
+
|
|
230
|
+
def from_image_bytes(self, img_bytes:bytes) -> PageDocumentPdf:
|
|
231
|
+
img_pil = Image.open(BytesIO(img_bytes))
|
|
232
|
+
buff_pdf = BytesIO()
|
|
233
|
+
|
|
234
|
+
# Converter e salvar como PDF
|
|
235
|
+
img_pil.save(buff_pdf, "PDF")
|
|
236
|
+
pdf_bytes:bytes = buff_pdf.getvalue()
|
|
237
|
+
buff_pdf.close()
|
|
238
|
+
return PageDocumentPdf.create_from_page_bytes(pdf_bytes, library=self._library_pdf)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
class ImageConvertPdf(ABCImageConvertPdf):
|
|
242
|
+
"""
|
|
243
|
+
Converter Imagem em páginas PDF.
|
|
244
|
+
"""
|
|
245
|
+
def __init__(self, convert_image_to_pdf:ABCImageConvertPdf):
|
|
246
|
+
super().__init__(convert_image_to_pdf.library_image)
|
|
247
|
+
self.convertImageToPdf:ABCImageConvertPdf = convert_image_to_pdf
|
|
248
|
+
self._count:int = 0
|
|
249
|
+
|
|
250
|
+
def from_image_file(self, file:File) -> PageDocumentPdf:
|
|
251
|
+
self._count += 1
|
|
252
|
+
print(f'{__class__.__name__}() Criando página PDF com arquivo de imagem {self._count}')
|
|
253
|
+
return self.convertImageToPdf.from_image_file(file)
|
|
254
|
+
|
|
255
|
+
def from_image(self, img:ImageObject) -> PageDocumentPdf:
|
|
256
|
+
if not isinstance(img, ImageObject):
|
|
257
|
+
raise ValueError(f'{__class__.__name__}\nUser: ImageObject(), não {type(img)}')
|
|
258
|
+
self._count += 1
|
|
259
|
+
print(f'{__class__.__name__}() Criando página PDF com objeto imagem {self._count}')
|
|
260
|
+
return self.convertImageToPdf.from_image(img)
|
|
261
|
+
|
|
262
|
+
def from_image_bytes(self, img_bytes) -> PageDocumentPdf:
|
|
263
|
+
self._count += 1
|
|
264
|
+
print(f'{__class__.__name__}() Criando página PDF com bytes de imagem {self._count}')
|
|
265
|
+
return self.convertImageToPdf.from_image_bytes(img_bytes)
|
|
266
|
+
|
|
267
|
+
@classmethod
|
|
268
|
+
def create_from_pil(cls, library_image:LibraryImage=LibraryImage.OPENCV) -> ImageConvertPdf:
|
|
269
|
+
img_convert:ABCImageConvertPdf = ImplementImageConvertToPdfPIL(library_image)
|
|
270
|
+
return cls(img_convert)
|
|
271
|
+
|
|
272
|
+
@classmethod
|
|
273
|
+
def create_from_canvas(cls, library_image:LibraryImage=LibraryImage.OPENCV) -> ImageConvertPdf:
|
|
274
|
+
img_convert:ABCImageConvertPdf = ImplementImageConvertPdfCanvas(library_image)
|
|
275
|
+
return cls(img_convert)
|
|
276
|
+
|
|
277
|
+
@classmethod
|
|
278
|
+
def create_from_fitz(cls, library_image:LibraryImage=LibraryImage.OPENCV) -> ImageConvertPdf:
|
|
279
|
+
img_convert:ABCImageConvertPdf = ImplementImageConvertPdfFitz(library_image)
|
|
280
|
+
return cls(img_convert)
|
|
281
|
+
|
|
282
|
+
|