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.

@@ -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
+