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.
Files changed (27) hide show
  1. {convert_stream-1.2 → convert_stream-1.2.1}/PKG-INFO +2 -2
  2. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/__init__.py +10 -5
  3. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/__main__.py +13 -4
  4. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/_version.py +2 -2
  5. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/convert.py +86 -61
  6. convert_stream-1.2.1/convert_stream/image_to_pdf.py +218 -0
  7. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/imagelib.py +1 -1
  8. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/models/models_image.py +3 -7
  9. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/models/models_pdf.py +23 -8
  10. convert_stream-1.2.1/convert_stream/pdf_compress.py +136 -0
  11. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/pdf_document.py +37 -8
  12. convert_stream-1.2.1/convert_stream/pdf_to_images.py +133 -0
  13. convert_stream-1.2.1/convert_stream/progress/__init__.py +0 -0
  14. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream.egg-info/PKG-INFO +2 -2
  15. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream.egg-info/SOURCES.txt +5 -2
  16. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream.egg-info/requires.txt +1 -1
  17. {convert_stream-1.2 → convert_stream-1.2.1}/pyproject.toml +8 -3
  18. convert_stream-1.2/convert_stream/pdf_convert.py +0 -294
  19. {convert_stream-1.2 → convert_stream-1.2.1}/README.md +0 -0
  20. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/models/__init__.py +0 -0
  21. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/models/m_text.py +0 -0
  22. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/pdf_page.py +0 -0
  23. {convert_stream-1.2/convert_stream/models → convert_stream-1.2.1/convert_stream/progress}/progress_bar.py +0 -0
  24. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream/text.py +0 -0
  25. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream.egg-info/dependency_links.txt +0 -0
  26. {convert_stream-1.2 → convert_stream-1.2.1}/convert_stream.egg-info/top_level.txt +0 -0
  27. {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==1.0.1
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__, __modify_date__
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 .models.progress_bar import (
15
- ProgressBarAdapter, ProgressBarSimple, ProgressBarTqdm, ABCProgressBar
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 .pdf_convert import ConvertPdfToImage, ImageConvertPdf
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 sys, os
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 PageDocumentPdf, PdfStream, DocumentPdf
26
- from soup_files import File, Directory, UserFileSystem
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()
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
- __version__ = '1.2'
3
+ __version__ = '1.2.1'
4
4
  __author__ = 'Bruno Chaves'
5
5
  __license__ = 'MIT'
6
6
  __module_name__ = 'pdflib'
7
- __modify_date__ = '2025-05-28'
7
+ __modify_date__ = '2025-06-21'
@@ -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.models.progress_bar import ProgressBarAdapter, ProgressBarSimple
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.pdf_convert import ConvertPdfToImage, ImageConvertPdf
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
- self, *,
26
- library_pdf: LibraryPDF = LibraryPDF.FITZ,
27
- library_image: LibraryImage = LibraryImage.OPENCV,
28
- progress_bar: ProgressBarAdapter = ProgressBarAdapter(ProgressBarSimple())
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.convertPdfToImages: ConvertPdfToImage = ConvertPdfToImage(library_image=library_image)
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.imagesToPdf:ImageConvertPdf = ImageConvertPdf.create_from_canvas(self.library_image)
42
+ self.convert_images_to_pdf: ImageConvertPdf = ImageConvertPdf.create_from_canvas(self.library_image)
39
43
  elif self.library_pdf == LibraryPDF.PILPDF:
40
- self.imagesToPdf:ImageConvertPdf = ImageConvertPdf.create_from_pil(LibraryImage.PIL)
44
+ self.convert_images_to_pdf: ImageConvertPdf = ImageConvertPdf.create_from_pil(LibraryImage.PIL)
41
45
  else:
42
- self.imagesToPdf:ImageConvertPdf = ImageConvertPdf.create_from_fitz(self.library_image)
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.imagesToPdf.from_image(image)
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(self.library_pdf, progress_bar=self.progress_bar)
113
- docpdf.add_pages(self.pages)
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__} Nenhuma página foi adiconada, adicione páginas ao documento para prosseguir!'
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
- print(f'Exportando página: {p.page_number} de {self.num_pages} | [{filename}]')
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='página-para-imagem'):
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.convertPdfToImages.from_page_pdf(page)
139
- print(f'Exportando página PDF para imagem: [{num+1} de {self.num_pages}] {filename}')
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
- images_obj.append(self.convertPdfToImages.from_page_pdf(page))
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
- doc = DocumentPdf(self.library_pdf)
150
- doc.add_pages(self.pages)
151
- return doc
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
- inner_images.extend(
157
- self.convertPdfToImages.inner_images(p.to_bytes())
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
- outdir = d #.concat(f'{num+1}')
166
- outdir.mkdir()
178
+ d.mkdir()
167
179
  for num, page in enumerate(self.pages):
168
- images = self.convertPdfToImages.inner_images(page.to_bytes())
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(outdir.join_file(filename))
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__(self, *, library_image=LibraryImage.OPENCV, library_pdf=LibraryPDF.PILPDF):
185
- self.__images:List[ImageObject] = []
186
- self.num_images:int = len(self.__images)
187
- self.library_image:LibraryImage = library_image
188
- self.library_pdf:LibraryPDF = library_pdf
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.convertImagesToPdf:ImageConvertPdf = ImageConvertPdf.create_from_fitz(library_image)
210
+ self.convert_image_to_pdf:ImageConvertPdf = ImageConvertPdf.create_from_fitz(library_image)
192
211
  elif library_pdf == LibraryPDF.CANVAS:
193
- self.convertImagesToPdf:ImageConvertPdf = ImageConvertPdf.create_from_canvas(library_image)
212
+ self.convert_image_to_pdf: ImageConvertPdf = ImageConvertPdf.create_from_canvas(library_image)
194
213
  elif library_pdf == LibraryPDF.PILPDF:
195
- self.convertImagesToPdf:ImageConvertPdf = ImageConvertPdf.create_from_pil(library_image)
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.convertPdfToImages:ConvertPdfToImage = ConvertPdfToImage(
199
- library_pdf=LibraryPDF.FITZ, library_image=library_image, dpi=200,
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
- print(f'Exportando imagem: {num+1} de {self.num_images} [{filename}]')
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.convertImagesToPdf.from_image(image))
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=80)
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
- @classmethod
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