convert-stream 1.2__tar.gz → 1.2.1__tar.gz
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.
- {convert_stream-1.2 → convert_stream-1.2.1}/PKG-INFO +2 -2
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/__init__.py +10 -5
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/__main__.py +13 -4
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/_version.py +2 -2
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/convert.py +86 -61
- convert_stream-1.2.1/convert_stream/image_to_pdf.py +218 -0
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/imagelib.py +1 -1
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/models/models_image.py +3 -7
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/models/models_pdf.py +23 -8
- convert_stream-1.2.1/convert_stream/pdf_compress.py +136 -0
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/pdf_document.py +37 -8
- convert_stream-1.2.1/convert_stream/pdf_to_images.py +133 -0
- convert_stream-1.2.1/convert_stream/progress/__init__.py +0 -0
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream.egg-info/PKG-INFO +2 -2
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream.egg-info/SOURCES.txt +5 -2
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream.egg-info/requires.txt +1 -1
- {convert_stream-1.2 → convert_stream-1.2.1}/pyproject.toml +8 -3
- convert_stream-1.2/convert_stream/pdf_convert.py +0 -294
- {convert_stream-1.2 → convert_stream-1.2.1}/README.md +0 -0
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/models/__init__.py +0 -0
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/models/m_text.py +0 -0
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/pdf_page.py +0 -0
- {convert_stream-1.2/convert_stream/models → convert_stream-1.2.1/convert_stream/progress}/progress_bar.py +0 -0
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/text.py +0 -0
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream.egg-info/dependency_links.txt +0 -0
- {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream.egg-info/top_level.txt +0 -0
- {convert_stream-1.2 → convert_stream-1.2.1}/setup.cfg +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: convert_stream
|
|
3
|
-
Version: 1.2
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Manipulação de documentos PDF e Imagens. Converter, Ler, rotacionar exportar etc.
|
|
5
5
|
Author: Bruno Chaves
|
|
6
6
|
Requires-Python: >=3.11
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
|
-
Requires-Dist: soup_files
|
|
8
|
+
Requires-Dist: soup_files
|
|
9
9
|
Requires-Dist: PyPDF2==3.0.1
|
|
10
10
|
Requires-Dist: PyMuPDF==1.25.5
|
|
11
11
|
Requires-Dist: reportlab==4.3.1
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
#
|
|
3
3
|
from ._version import (
|
|
4
4
|
__version__, __module_name__,
|
|
5
|
-
__author__, __license__,
|
|
5
|
+
__author__, __license__,
|
|
6
|
+
__modify_date__
|
|
6
7
|
)
|
|
7
8
|
version = __version__
|
|
8
9
|
|
|
@@ -11,13 +12,17 @@ from .text import (
|
|
|
11
12
|
LibraryDates, print_title, print_line, save_data
|
|
12
13
|
)
|
|
13
14
|
|
|
14
|
-
from .
|
|
15
|
-
ProgressBarAdapter, ProgressBarSimple,
|
|
15
|
+
from convert_stream.progress.progress_bar import (
|
|
16
|
+
ProgressBarAdapter, ProgressBarSimple,
|
|
17
|
+
ProgressBarTqdm, ABCProgressBar
|
|
16
18
|
)
|
|
19
|
+
|
|
17
20
|
from .models.models_pdf import LibraryPDF
|
|
18
21
|
from .imagelib import ImageObject, ImageInverColor, LibraryImage
|
|
19
22
|
from .pdf_page import PageDocumentPdf, PagePdfFitz, PagePyPdf2
|
|
20
|
-
from .pdf_document import DocumentPdf
|
|
21
|
-
from .
|
|
23
|
+
from .pdf_document import DocumentPdf, FileDocumentPdf
|
|
24
|
+
from .pdf_to_images import ConvertPdfToImage
|
|
25
|
+
from .image_to_pdf import ImageConvertPdf
|
|
22
26
|
from .convert import PdfStream, ImageStream, get_data_from_pdfs
|
|
27
|
+
from .pdf_compress import CompressDocument
|
|
23
28
|
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
+ Incluir o método set_rotation() em ImageObject()
|
|
12
12
|
|
|
13
13
|
"""
|
|
14
|
-
import
|
|
14
|
+
import os
|
|
15
|
+
import sys
|
|
16
|
+
|
|
15
17
|
this_file = os.path.abspath(os.path.relpath(__file__))
|
|
16
18
|
dir_of_project = os.path.dirname(this_file)
|
|
17
19
|
sys.path.insert(0, dir_of_project)
|
|
@@ -22,13 +24,20 @@ from convert_stream import (
|
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
def test():
|
|
25
|
-
from convert_stream import
|
|
26
|
-
from soup_files import
|
|
27
|
+
from convert_stream import FileDocumentPdf, CompressDocument, DocumentPdf
|
|
28
|
+
from soup_files import Directory, File, UserFileSystem
|
|
29
|
+
|
|
30
|
+
outdir = UserFileSystem().userDownloads.concat('output', create=True)
|
|
31
|
+
base = UserFileSystem().userDownloads.join_file('base.pdf')
|
|
32
|
+
|
|
33
|
+
comp = CompressDocument.create_from_file(base, dpi=100)
|
|
34
|
+
comp.to_file(outdir.join_file('teste.pdf'))
|
|
27
35
|
|
|
28
36
|
|
|
29
37
|
def main():
|
|
30
38
|
print_title(f'{__module_name__} versão {version} - {__modify_date__}', char='-')
|
|
31
39
|
test()
|
|
32
40
|
|
|
41
|
+
|
|
33
42
|
if __name__ == '__main__':
|
|
34
|
-
main()
|
|
43
|
+
main()
|
|
@@ -6,47 +6,51 @@ import pandas
|
|
|
6
6
|
|
|
7
7
|
from convert_stream.models import ABCDocumentStream, LibraryImage, LibraryPDF
|
|
8
8
|
from convert_stream.imagelib import ImageObject
|
|
9
|
-
from convert_stream.
|
|
9
|
+
from convert_stream.progress.progress_bar import ProgressBarAdapter, ProgressBarSimple
|
|
10
10
|
from convert_stream.pdf_page import PageDocumentPdf
|
|
11
11
|
from convert_stream.pdf_document import DocumentPdf
|
|
12
|
-
from convert_stream.
|
|
12
|
+
from convert_stream.pdf_to_images import ConvertPdfToImage
|
|
13
|
+
from convert_stream.image_to_pdf import ImageConvertPdf
|
|
13
14
|
from soup_files import File, Directory
|
|
14
15
|
|
|
15
16
|
#==================================================================#
|
|
16
17
|
# PDF
|
|
17
18
|
#==================================================================#
|
|
18
19
|
|
|
20
|
+
|
|
19
21
|
class PdfStream(ABCDocumentStream):
|
|
20
22
|
"""
|
|
21
23
|
Objeto para manipular a exportação de dados PDF
|
|
22
24
|
"""
|
|
23
25
|
|
|
24
26
|
def __init__(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
self, *,
|
|
28
|
+
library_pdf: LibraryPDF = LibraryPDF.FITZ,
|
|
29
|
+
library_image: LibraryImage = LibraryImage.OPENCV,
|
|
30
|
+
progress_bar: ProgressBarAdapter = ProgressBarAdapter(ProgressBarSimple())
|
|
29
31
|
):
|
|
30
32
|
super().__init__(library_pdf=library_pdf, library_image=library_image, progress_bar=progress_bar)
|
|
31
33
|
self.num_pages: int = 0
|
|
32
34
|
self.library_pdf: LibraryPDF = library_pdf
|
|
33
35
|
self.library_image: LibraryImage = library_image
|
|
34
36
|
self.document: DocumentPdf = DocumentPdf(self.library_pdf, progress_bar=progress_bar)
|
|
35
|
-
self.
|
|
37
|
+
self.convert_pdf_to_images: ConvertPdfToImage = ConvertPdfToImage(
|
|
38
|
+
library_image=library_image, progress_bar=progress_bar
|
|
39
|
+
)
|
|
36
40
|
|
|
37
41
|
if self.library_pdf == LibraryPDF.CANVAS:
|
|
38
|
-
self.
|
|
42
|
+
self.convert_images_to_pdf: ImageConvertPdf = ImageConvertPdf.create_from_canvas(self.library_image)
|
|
39
43
|
elif self.library_pdf == LibraryPDF.PILPDF:
|
|
40
|
-
self.
|
|
44
|
+
self.convert_images_to_pdf: ImageConvertPdf = ImageConvertPdf.create_from_pil(LibraryImage.PIL)
|
|
41
45
|
else:
|
|
42
|
-
self.
|
|
46
|
+
self.convert_images_to_pdf: ImageConvertPdf = ImageConvertPdf.create_from_fitz(self.library_image)
|
|
43
47
|
|
|
44
48
|
@property
|
|
45
49
|
def num_pages(self) -> int:
|
|
46
50
|
return self.document.num_pages
|
|
47
51
|
|
|
48
52
|
@num_pages.setter
|
|
49
|
-
def num_pages(self, num:int):
|
|
53
|
+
def num_pages(self, num: int):
|
|
50
54
|
pass
|
|
51
55
|
|
|
52
56
|
@property
|
|
@@ -54,7 +58,7 @@ class PdfStream(ABCDocumentStream):
|
|
|
54
58
|
return self.document.pages
|
|
55
59
|
|
|
56
60
|
@pages.setter
|
|
57
|
-
def pages(self, new:List[PageDocumentPdf]):
|
|
61
|
+
def pages(self, new: List[PageDocumentPdf]):
|
|
58
62
|
if not isinstance(new, list):
|
|
59
63
|
return
|
|
60
64
|
self.document.clear()
|
|
@@ -67,7 +71,7 @@ class PdfStream(ABCDocumentStream):
|
|
|
67
71
|
def clear(self):
|
|
68
72
|
self.document.clear()
|
|
69
73
|
|
|
70
|
-
def add_page(self, p:PageDocumentPdf):
|
|
74
|
+
def add_page(self, p: PageDocumentPdf):
|
|
71
75
|
if not isinstance(p, PageDocumentPdf):
|
|
72
76
|
return
|
|
73
77
|
self.document.add_page(p)
|
|
@@ -101,7 +105,7 @@ class PdfStream(ABCDocumentStream):
|
|
|
101
105
|
self.add_pages(doc.pages)
|
|
102
106
|
|
|
103
107
|
def add_image(self, image: ImageObject):
|
|
104
|
-
pg: PageDocumentPdf = self.
|
|
108
|
+
pg: PageDocumentPdf = self.convert_images_to_pdf.from_image(image)
|
|
105
109
|
self.add_page(pg)
|
|
106
110
|
|
|
107
111
|
def to_file_pdf(self, f: File):
|
|
@@ -109,94 +113,112 @@ class PdfStream(ABCDocumentStream):
|
|
|
109
113
|
print(
|
|
110
114
|
f'{__class__.__name__} Nenhuma página foi adiconada, adicione páginas ao documento para prosseguir!'
|
|
111
115
|
)
|
|
112
|
-
docpdf: DocumentPdf = DocumentPdf(
|
|
113
|
-
|
|
116
|
+
docpdf: DocumentPdf = DocumentPdf(
|
|
117
|
+
self.library_pdf, progress_bar=self.progress_bar, pages=self.pages
|
|
118
|
+
)
|
|
114
119
|
docpdf.to_file_pdf(f)
|
|
115
120
|
|
|
116
|
-
def to_files_pdf(self, outdir: Directory, *, prefix='pag'):
|
|
121
|
+
def to_files_pdf(self, outdir: Directory, *, prefix='documento-pag'):
|
|
117
122
|
if self.is_null():
|
|
118
123
|
print(
|
|
119
|
-
f'{__class__.__name__}
|
|
124
|
+
f'{__class__.__name__} Adicione páginas ao documento para prosseguir!'
|
|
120
125
|
)
|
|
121
|
-
|
|
126
|
+
return
|
|
122
127
|
outdir.mkdir()
|
|
123
|
-
_document:DocumentPdf = DocumentPdf(self.library_pdf)
|
|
128
|
+
_document: DocumentPdf = DocumentPdf(self.library_pdf)
|
|
124
129
|
for num, p in enumerate(self.pages):
|
|
125
|
-
filename:str = f'{prefix}-{num+1}.pdf'
|
|
126
|
-
|
|
130
|
+
filename: str = f'{prefix}-{num+1}.pdf'
|
|
131
|
+
self.progress_bar.update_text(
|
|
132
|
+
f'Exportando página: {p.page_number} de {self.num_pages} | [{filename}]'
|
|
133
|
+
)
|
|
127
134
|
_document.add_page(p)
|
|
128
135
|
_document.to_file_pdf(outdir.join_file(filename))
|
|
129
136
|
_document.clear()
|
|
130
137
|
|
|
131
|
-
def to_files_image(self, d:Directory, *, prefix:str='
|
|
138
|
+
def to_files_image(self, d: Directory, *, prefix: str = 'pdf-para-imagem'):
|
|
132
139
|
"""
|
|
133
140
|
Exporta cada página PDF como um arquivo de imagem.
|
|
134
141
|
"""
|
|
135
142
|
d.mkdir()
|
|
136
143
|
for num, page in enumerate(self.pages):
|
|
137
144
|
filename = f'{prefix}-{page.page_number}.png'
|
|
138
|
-
img = self.
|
|
139
|
-
|
|
145
|
+
img = self.convert_pdf_to_images.from_page_pdf(page)
|
|
146
|
+
self.progress_bar.update_text(
|
|
147
|
+
f'Exportando página PDF para imagem: [{num+1} de {self.num_pages}] {filename}'
|
|
148
|
+
)
|
|
140
149
|
img.to_file(d.join_file(filename))
|
|
141
150
|
|
|
142
151
|
def to_images(self) -> List[ImageObject]:
|
|
143
|
-
images_obj:List[ImageObject] = []
|
|
152
|
+
images_obj: List[ImageObject] = []
|
|
144
153
|
for page in self.pages:
|
|
145
|
-
|
|
154
|
+
_image: ImageObject = self.convert_pdf_to_images.from_page_pdf(page)
|
|
155
|
+
images_obj.append(_image)
|
|
146
156
|
return images_obj
|
|
147
157
|
|
|
148
158
|
def to_document(self) -> DocumentPdf:
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
159
|
+
return DocumentPdf(
|
|
160
|
+
self.library_pdf, progress_bar=self.progress_bar, pages=self.pages
|
|
161
|
+
)
|
|
152
162
|
|
|
153
163
|
def inner_images(self) -> List[ImageObject]:
|
|
154
|
-
inner_images:List[ImageObject] = []
|
|
155
|
-
for p in self.pages:
|
|
156
|
-
|
|
157
|
-
|
|
164
|
+
inner_images: List[ImageObject] = []
|
|
165
|
+
for num, p in enumerate(self.pages):
|
|
166
|
+
self.progress_bar.update(
|
|
167
|
+
((num+1)/self.num_pages) * 100,
|
|
168
|
+
f'Convertendo página [{num+1} de {self.num_pages}]'
|
|
158
169
|
)
|
|
170
|
+
imgs: List[ImageObject] = self.convert_pdf_to_images.inner_images(p.to_bytes())
|
|
171
|
+
inner_images.extend(imgs)
|
|
159
172
|
return inner_images
|
|
160
173
|
|
|
161
|
-
def inner_images_to_files(self, d:Directory, prefix:str='página-para-imagens') -> None:
|
|
174
|
+
def inner_images_to_files(self, d: Directory, prefix: str = 'página-para-imagens') -> None:
|
|
162
175
|
"""
|
|
163
|
-
Salva todas as imagens presentes nas páginas em arquivos de imagem.
|
|
176
|
+
Salva todas as imagens presentes nas páginas PDF, em arquivos de imagem.
|
|
164
177
|
"""
|
|
165
|
-
|
|
166
|
-
outdir.mkdir()
|
|
178
|
+
d.mkdir()
|
|
167
179
|
for num, page in enumerate(self.pages):
|
|
168
|
-
images = self.
|
|
180
|
+
images = self.convert_pdf_to_images.inner_images(page.to_bytes())
|
|
169
181
|
if len(images) < 1:
|
|
170
182
|
continue
|
|
171
183
|
for n, img in enumerate(images):
|
|
172
184
|
filename = f'{prefix}-{page.page_number}-img-{n+1}.png'
|
|
173
|
-
img.to_file(
|
|
185
|
+
img.to_file(d.join_file(filename))
|
|
174
186
|
|
|
175
187
|
def set_paisagem(self):
|
|
176
188
|
for page in self.pages:
|
|
177
189
|
page.set_paisagem()
|
|
178
|
-
|
|
190
|
+
|
|
191
|
+
|
|
179
192
|
#==================================================================#
|
|
180
193
|
# Imagens
|
|
181
194
|
#==================================================================#
|
|
182
195
|
|
|
183
196
|
class ImageStream(object):
|
|
184
|
-
def __init__(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
197
|
+
def __init__(
|
|
198
|
+
self, *,
|
|
199
|
+
library_image = LibraryImage.OPENCV,
|
|
200
|
+
library_pdf = LibraryPDF.PILPDF,
|
|
201
|
+
progress_bar: ProgressBarAdapter = ProgressBarAdapter(ProgressBarSimple()),
|
|
202
|
+
):
|
|
203
|
+
self.__images: List[ImageObject] = []
|
|
204
|
+
self.num_images: int = len(self.__images)
|
|
205
|
+
self.progress_bar: ProgressBarAdapter = progress_bar
|
|
206
|
+
self.library_image: LibraryImage = library_image
|
|
207
|
+
self.library_pdf: LibraryPDF = library_pdf
|
|
189
208
|
# Objeto para converter IMAGEM em pdf.
|
|
190
209
|
if library_pdf == LibraryPDF.FITZ:
|
|
191
|
-
self.
|
|
210
|
+
self.convert_image_to_pdf:ImageConvertPdf = ImageConvertPdf.create_from_fitz(library_image)
|
|
192
211
|
elif library_pdf == LibraryPDF.CANVAS:
|
|
193
|
-
self.
|
|
212
|
+
self.convert_image_to_pdf: ImageConvertPdf = ImageConvertPdf.create_from_canvas(library_image)
|
|
194
213
|
elif library_pdf == LibraryPDF.PILPDF:
|
|
195
|
-
self.
|
|
214
|
+
self.convert_image_to_pdf: ImageConvertPdf = ImageConvertPdf.create_from_pil(library_image)
|
|
196
215
|
|
|
197
216
|
# Objeto para converter PDF em imagem
|
|
198
|
-
self.
|
|
199
|
-
library_pdf=LibraryPDF.FITZ,
|
|
217
|
+
self.convert_pdf_to_images: ConvertPdfToImage = ConvertPdfToImage(
|
|
218
|
+
library_pdf=LibraryPDF.FITZ,
|
|
219
|
+
library_image=library_image,
|
|
220
|
+
dpi=150,
|
|
221
|
+
progress_bar=progress_bar,
|
|
200
222
|
)
|
|
201
223
|
|
|
202
224
|
@property
|
|
@@ -204,7 +226,7 @@ class ImageStream(object):
|
|
|
204
226
|
return self.__images
|
|
205
227
|
|
|
206
228
|
@images.setter
|
|
207
|
-
def images(self, imgs:List[ImageObject]) -> None:
|
|
229
|
+
def images(self, imgs: List[ImageObject]) -> None:
|
|
208
230
|
if not isinstance(imgs, list):
|
|
209
231
|
print(f'Erro: Use: list() não {type(imgs)}')
|
|
210
232
|
return
|
|
@@ -212,14 +234,14 @@ class ImageStream(object):
|
|
|
212
234
|
for img in imgs:
|
|
213
235
|
self.add_image(img)
|
|
214
236
|
|
|
215
|
-
def add_image(self, img:ImageObject) -> None:
|
|
237
|
+
def add_image(self, img: ImageObject) -> None:
|
|
216
238
|
if not isinstance(img, ImageObject):
|
|
217
239
|
return
|
|
218
240
|
print(f'{__class__.__name__} Adicionando imagem {self.num_images+1}')
|
|
219
241
|
self.__images.append(img)
|
|
220
242
|
self.num_images += 1
|
|
221
243
|
|
|
222
|
-
def add_images(self, images:List[ImageObject]):
|
|
244
|
+
def add_images(self, images: List[ImageObject]):
|
|
223
245
|
for i in images:
|
|
224
246
|
self.add_image(i)
|
|
225
247
|
|
|
@@ -227,7 +249,7 @@ class ImageStream(object):
|
|
|
227
249
|
img = ImageObject.create_from_file(f, library=self.library_image)
|
|
228
250
|
self.add_image(img)
|
|
229
251
|
|
|
230
|
-
def add_files_image(self, files:List[File]):
|
|
252
|
+
def add_files_image(self, files: List[File]):
|
|
231
253
|
for f in files:
|
|
232
254
|
self.add_file_image(f)
|
|
233
255
|
|
|
@@ -240,11 +262,14 @@ class ImageStream(object):
|
|
|
240
262
|
self.__images.clear()
|
|
241
263
|
self.num_images = 0
|
|
242
264
|
|
|
243
|
-
def to_files_image(self, d:Directory, prefix:str='imagem'):
|
|
265
|
+
def to_files_image(self, d: Directory, prefix: str = 'imagem'):
|
|
244
266
|
d.mkdir()
|
|
245
267
|
for num, image in enumerate(self.images):
|
|
246
268
|
filename = f'{prefix}-{num+1}.png'
|
|
247
|
-
|
|
269
|
+
self.progress_bar.update(
|
|
270
|
+
((num+1)/self.num_images) * 100,
|
|
271
|
+
f'Exportando imagem: {num+1} de {self.num_images} [{filename}]'
|
|
272
|
+
)
|
|
248
273
|
image.to_file(d.join_file(filename))
|
|
249
274
|
|
|
250
275
|
def to_pages_pdf(self) -> List[PageDocumentPdf]:
|
|
@@ -253,7 +278,7 @@ class ImageStream(object):
|
|
|
253
278
|
return []
|
|
254
279
|
new_pages = []
|
|
255
280
|
for image in self.images:
|
|
256
|
-
new_pages.append(self.
|
|
281
|
+
new_pages.append(self.convert_image_to_pdf.from_image(image))
|
|
257
282
|
return new_pages
|
|
258
283
|
|
|
259
284
|
def set_paisagem(self):
|
|
@@ -281,15 +306,15 @@ class ImageStream(object):
|
|
|
281
306
|
self.images[num].set_optimize()
|
|
282
307
|
|
|
283
308
|
|
|
284
|
-
def get_data_from_pdfs(*, files_pdf:List[File]) -> pandas.DataFrame:
|
|
309
|
+
def get_data_from_pdfs(*, files_pdf: List[File]) -> pandas.DataFrame:
|
|
285
310
|
"""
|
|
286
311
|
Recebe uma lista de arquivos PDF e retorna um DataFrame com os dados das cartas.
|
|
287
312
|
"""
|
|
288
313
|
if not isinstance(files_pdf, list):
|
|
289
314
|
raise ValueError(f'Erro: Use: list() não {type(files_pdf)}')
|
|
290
315
|
|
|
291
|
-
data:List[pandas.DataFrame] = []
|
|
292
|
-
values:List[str] = []
|
|
316
|
+
data: List[pandas.DataFrame] = []
|
|
317
|
+
values: List[str] = []
|
|
293
318
|
doc = DocumentPdf()
|
|
294
319
|
for file in files_pdf:
|
|
295
320
|
doc.add_file_pdf(file)
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from typing import List
|
|
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
|
+
from soup_files import File
|
|
12
|
+
|
|
13
|
+
from convert_stream.models import ABCImageObject, ABCPagePdf
|
|
14
|
+
from convert_stream.imagelib import ImageObject, LibraryImage
|
|
15
|
+
from convert_stream.models.models_pdf import ABCConvertPdf, ABCImageConvertPdf, LibraryPDF
|
|
16
|
+
from convert_stream.progress.progress_bar import ProgressBarAdapter, ProgressBarSimple
|
|
17
|
+
|
|
18
|
+
from convert_stream.pdf_page import (
|
|
19
|
+
PageDocumentPdf, MODULE_PYPDF2, MODULE_FITZ
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
if MODULE_PYPDF2:
|
|
23
|
+
from PyPDF2 import PdfReader, PdfWriter, PageObject
|
|
24
|
+
if MODULE_FITZ:
|
|
25
|
+
try:
|
|
26
|
+
import fitz
|
|
27
|
+
except:
|
|
28
|
+
try:
|
|
29
|
+
import pymupdf
|
|
30
|
+
except:
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
#########################################################################
|
|
35
|
+
# Converter IMAGEM para Arquivo ou página PDF.
|
|
36
|
+
#########################################################################
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ImplementImageConvertPdfFitz(ABCImageConvertPdf):
|
|
40
|
+
"""
|
|
41
|
+
Implementação para converter imagens em PDF.
|
|
42
|
+
"""
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
library_image, *,
|
|
46
|
+
progress_bar: ProgressBarAdapter = ProgressBarAdapter(ProgressBarSimple())
|
|
47
|
+
):
|
|
48
|
+
super().__init__(library_image, progress_bar=progress_bar)
|
|
49
|
+
self._library_pdf = LibraryPDF.FITZ
|
|
50
|
+
|
|
51
|
+
def from_image_file(self, file: File) -> PageDocumentPdf:
|
|
52
|
+
# https://pymupdf.readthedocs.io/en/latest/recipes-images.html
|
|
53
|
+
doc = fitz.Document()
|
|
54
|
+
img_document: fitz.Document = fitz.Document(file.absolute()) # open pic as document
|
|
55
|
+
rect = img_document[0].rect # pic dimension
|
|
56
|
+
pdfbytes = img_document.convert_to_pdf() # make a PDF stream
|
|
57
|
+
img_document.close() # no longer needed
|
|
58
|
+
image_doc_pdf = fitz.Document("pdf", pdfbytes) # open stream as PDF
|
|
59
|
+
|
|
60
|
+
page = doc.new_page(
|
|
61
|
+
width=rect.width, # new page with ...
|
|
62
|
+
height=rect.height # pic dimension
|
|
63
|
+
)
|
|
64
|
+
page.show_pdf_page(rect, image_doc_pdf, 0) # image fills the page
|
|
65
|
+
return PageDocumentPdf.create_from_page_fitz(page)
|
|
66
|
+
|
|
67
|
+
def from_image(self, img: ImageObject) -> PageDocumentPdf:
|
|
68
|
+
return self.from_image_bytes(img.to_bytes())
|
|
69
|
+
|
|
70
|
+
def from_image_bytes(self, image_bytes: bytes) -> PageDocumentPdf:
|
|
71
|
+
doc: fitz.Document = fitz.Document()
|
|
72
|
+
|
|
73
|
+
# Criar um Pixmap diretamente dos bytes da imagem
|
|
74
|
+
pix = fitz.Pixmap(BytesIO(image_bytes))
|
|
75
|
+
|
|
76
|
+
# Criar uma nova página do tamanho da imagem
|
|
77
|
+
page = doc.new_page(width=pix.width, height=pix.height)
|
|
78
|
+
|
|
79
|
+
# Inserir a imagem na página
|
|
80
|
+
page.insert_image(page.rect, pixmap=pix)
|
|
81
|
+
return PageDocumentPdf.create_from_page_fitz(page)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ImplementImageConvertPdfCanvas(ABCImageConvertPdf):
|
|
85
|
+
"""
|
|
86
|
+
Implementação para converter uma imagem em página PDF (canvas).
|
|
87
|
+
"""
|
|
88
|
+
def __init__(self, library_image):
|
|
89
|
+
super().__init__(library_image)
|
|
90
|
+
self._library_pdf = LibraryPDF.FITZ
|
|
91
|
+
|
|
92
|
+
def from_image(self, img: ImageObject) -> PageDocumentPdf:
|
|
93
|
+
# Cria um buffer de memória para o PDF
|
|
94
|
+
buffer_pdf = BytesIO()
|
|
95
|
+
|
|
96
|
+
# Cria o canvas associado ao buffer
|
|
97
|
+
c: Canvas = canvas.Canvas(buffer_pdf, pagesize=letter)
|
|
98
|
+
# Adicionar a imagem.
|
|
99
|
+
c.drawImage(
|
|
100
|
+
ImageReader(img.to_image_pil()),
|
|
101
|
+
0,
|
|
102
|
+
0,
|
|
103
|
+
width=letter[0],
|
|
104
|
+
height=letter[1],
|
|
105
|
+
preserveAspectRatio=True,
|
|
106
|
+
anchor='c'
|
|
107
|
+
)
|
|
108
|
+
c.showPage()
|
|
109
|
+
|
|
110
|
+
# Finaliza o PDF
|
|
111
|
+
c.save()
|
|
112
|
+
|
|
113
|
+
# Move o ponteiro do buffer para o início
|
|
114
|
+
buffer_pdf.seek(0)
|
|
115
|
+
|
|
116
|
+
# Obtém os bytes do PDF
|
|
117
|
+
pdf_bytes = buffer_pdf.getvalue()
|
|
118
|
+
|
|
119
|
+
# Fecha o buffer (opcional, mas recomendado)
|
|
120
|
+
buffer_pdf.close()
|
|
121
|
+
|
|
122
|
+
# Gerar a página PDF
|
|
123
|
+
return PageDocumentPdf.create_from_page_bytes(pdf_bytes, library=self._library_pdf)
|
|
124
|
+
|
|
125
|
+
def from_image_file(self, file:File) -> PageDocumentPdf:
|
|
126
|
+
"""
|
|
127
|
+
Converter um arquivo de imagem em páginas PDF
|
|
128
|
+
"""
|
|
129
|
+
img = ImageObject.create_from_file(file, library=self.library_image)
|
|
130
|
+
return self.from_image(img)
|
|
131
|
+
|
|
132
|
+
def from_image_bytes(self, img_bytes:bytes) -> PageDocumentPdf:
|
|
133
|
+
return self.from_image(
|
|
134
|
+
ImageObject.create_from_bytes(img_bytes, library=self.library_image)
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class ImplementImageConvertToPdfPIL(ABCImageConvertPdf):
|
|
139
|
+
"""
|
|
140
|
+
Implementação para converter uma imagem em página PDF (PIL).
|
|
141
|
+
"""
|
|
142
|
+
def __init__(self, library_image):
|
|
143
|
+
super().__init__(library_image)
|
|
144
|
+
self._library_pdf: LibraryPDF = LibraryPDF.FITZ
|
|
145
|
+
|
|
146
|
+
def from_image(self, img:ImageObject) -> PageDocumentPdf:
|
|
147
|
+
img_pil = img.to_image_pil()
|
|
148
|
+
buff = BytesIO()
|
|
149
|
+
# Converter e salvar como PDF
|
|
150
|
+
img_pil.save(buff, "PDF")
|
|
151
|
+
pdf_bytes: bytes = buff.getvalue()
|
|
152
|
+
buff.close()
|
|
153
|
+
return PageDocumentPdf.create_from_page_bytes(pdf_bytes, library=self._library_pdf)
|
|
154
|
+
|
|
155
|
+
def from_image_file(self, file: File) -> PageDocumentPdf:
|
|
156
|
+
"""
|
|
157
|
+
Converter um arquivo de imagem em páginas PDF
|
|
158
|
+
"""
|
|
159
|
+
# Carregar a imagem
|
|
160
|
+
imagem:Image.Image = Image.open(file.absolute())
|
|
161
|
+
buff = BytesIO()
|
|
162
|
+
# Converter e salvar como PDF
|
|
163
|
+
imagem.save(buff, "PDF")
|
|
164
|
+
pdf_bytes: bytes = buff.getvalue()
|
|
165
|
+
buff.close()
|
|
166
|
+
return PageDocumentPdf.create_from_page_bytes(pdf_bytes, library=self._library_pdf)
|
|
167
|
+
|
|
168
|
+
def from_image_bytes(self, img_bytes:bytes) -> PageDocumentPdf:
|
|
169
|
+
img_pil = Image.open(BytesIO(img_bytes))
|
|
170
|
+
buff_pdf = BytesIO()
|
|
171
|
+
# Converter e salvar como PDF
|
|
172
|
+
img_pil.save(buff_pdf, "PDF")
|
|
173
|
+
pdf_bytes: bytes = buff_pdf.getvalue()
|
|
174
|
+
buff_pdf.close()
|
|
175
|
+
return PageDocumentPdf.create_from_page_bytes(pdf_bytes, library=self._library_pdf)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class ImageConvertPdf(ABCImageConvertPdf):
|
|
179
|
+
"""
|
|
180
|
+
Converter Imagem em páginas PDF.
|
|
181
|
+
"""
|
|
182
|
+
def __init__(self, convert_image_to_pdf: ABCImageConvertPdf):
|
|
183
|
+
super().__init__(convert_image_to_pdf.library_image)
|
|
184
|
+
self.convert_image_to_pdf: ABCImageConvertPdf = convert_image_to_pdf
|
|
185
|
+
|
|
186
|
+
def from_image_file(self, file: File) -> PageDocumentPdf:
|
|
187
|
+
return self.convert_image_to_pdf.from_image_file(file)
|
|
188
|
+
|
|
189
|
+
def from_image(self, img: ImageObject) -> PageDocumentPdf:
|
|
190
|
+
if not isinstance(img, ImageObject):
|
|
191
|
+
raise ValueError(f'{__class__.__name__}\nUser: ImageObject(), não {type(img)}')
|
|
192
|
+
return self.convert_image_to_pdf.from_image(img)
|
|
193
|
+
|
|
194
|
+
def from_image_bytes(self, img_bytes) -> PageDocumentPdf:
|
|
195
|
+
return self.convert_image_to_pdf.from_image_bytes(img_bytes)
|
|
196
|
+
|
|
197
|
+
@classmethod
|
|
198
|
+
def create_from_pil(cls, library_image:LibraryImage=LibraryImage.OPENCV) -> ImageConvertPdf:
|
|
199
|
+
img_convert: ABCImageConvertPdf = ImplementImageConvertToPdfPIL(library_image)
|
|
200
|
+
return cls(img_convert)
|
|
201
|
+
|
|
202
|
+
@classmethod
|
|
203
|
+
def create_from_canvas(
|
|
204
|
+
cls,
|
|
205
|
+
library_image: LibraryImage = LibraryImage.OPENCV
|
|
206
|
+
) -> ImageConvertPdf:
|
|
207
|
+
img_convert = ImplementImageConvertPdfCanvas(library_image)
|
|
208
|
+
return cls(img_convert)
|
|
209
|
+
|
|
210
|
+
@classmethod
|
|
211
|
+
def create_from_fitz(
|
|
212
|
+
cls,
|
|
213
|
+
library_image: LibraryImage = LibraryImage.OPENCV
|
|
214
|
+
) -> ImageConvertPdf:
|
|
215
|
+
img_convert = ImplementImageConvertPdfFitz(library_image)
|
|
216
|
+
return cls(img_convert)
|
|
217
|
+
|
|
218
|
+
|
|
@@ -267,7 +267,7 @@ class ImageObjectPIL(ABCImageObject):
|
|
|
267
267
|
def set_optimize(self):
|
|
268
268
|
optimized_bytes = BytesIO()
|
|
269
269
|
img = self.to_image_pil()
|
|
270
|
-
img.save(optimized_bytes, format='PNG', optimize=True, quality=
|
|
270
|
+
img.save(optimized_bytes, format='PNG', optimize=True, quality=70)
|
|
271
271
|
self.image_bytes = optimized_bytes.getvalue()
|
|
272
272
|
|
|
273
273
|
def set_background_black(self):
|
|
@@ -15,8 +15,7 @@ class LibraryImage(Enum):
|
|
|
15
15
|
ROTATION_90 = 90
|
|
16
16
|
ROTATION_180 = 180
|
|
17
17
|
ROTATION_270 = 270
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
|
|
20
19
|
|
|
21
20
|
class ABCInvertColor(ABC):
|
|
22
21
|
|
|
@@ -49,7 +48,7 @@ class ABCImageObject(ABC):
|
|
|
49
48
|
super().__init__()
|
|
50
49
|
self.current_library: LibraryImage = None
|
|
51
50
|
|
|
52
|
-
@
|
|
51
|
+
@abstractmethod
|
|
53
52
|
def is_paisagem(self) -> bool:
|
|
54
53
|
"""
|
|
55
54
|
Retorna True se a imagem estiver em modo paisagem.
|
|
@@ -99,8 +98,5 @@ class ABCImageObject(ABC):
|
|
|
99
98
|
"""
|
|
100
99
|
pass
|
|
101
100
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
|
|
106
102
|
|