-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
177 lines (141 loc) · 6.02 KB
/
app.py
File metadata and controls
177 lines (141 loc) · 6.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import gradio as gr
import fitz # PyMuPDF
from PIL import Image
import io
import os
class PDFViewer:
def __init__(self):
self.current_doc = None
self.total_pages = 0
self.current_page = 0
def load_pdf(self, pdf_file):
"""Carga un archivo PDF y retorna la primera página"""
if pdf_file is None:
return None, "No se ha seleccionado ningún archivo", gr.update(choices=[], value=None), gr.update(visible=False)
try:
# Abrir el documento PDF
self.current_doc = fitz.open(pdf_file.name)
self.total_pages = len(self.current_doc)
self.current_page = 0
# Crear lista de páginas para el dropdown
page_choices = [f"Página {i+1}" for i in range(self.total_pages)]
# Obtener la primera página
first_page_image = self.get_page_image(0)
info_text = f"PDF cargado: {self.total_pages} páginas"
return (
first_page_image,
info_text,
gr.update(choices=page_choices, value="Página 1", visible=True),
gr.update(visible=True) # Mostrar controles de navegación
)
except Exception as e:
return None, f"Error al cargar PDF: {str(e)}", gr.update(choices=[], value=None), gr.update(visible=False)
def get_page_image(self, page_num):
"""Convierte una página del PDF a imagen"""
if self.current_doc is None or page_num >= self.total_pages:
return None
# Obtener la página
page = self.current_doc.load_page(page_num)
# Convertir a imagen con buena resolución
mat = fitz.Matrix(2.0, 2.0) # Factor de escala para mejor calidad
pix = page.get_pixmap(matrix=mat)
# Convertir a PIL Image
img_data = pix.tobytes("png")
img = Image.open(io.BytesIO(img_data))
return img
def navigate_to_page(self, page_selection):
"""Navega a la página seleccionada"""
if self.current_doc is None or page_selection is None:
return None, "No hay PDF cargado"
try:
# Extraer número de página del texto seleccionado
page_num = int(page_selection.split()[-1]) - 1
self.current_page = page_num
# Obtener imagen de la página
page_image = self.get_page_image(page_num)
info_text = f"Mostrando página {page_num + 1} de {self.total_pages}"
return page_image, info_text
except Exception as e:
return None, f"Error al navegar: {str(e)}"
def prev_page(self):
"""Ir a la página anterior"""
if self.current_doc is None:
return None, "No hay PDF cargado", gr.update()
if self.current_page > 0:
self.current_page -= 1
page_image = self.get_page_image(self.current_page)
info_text = f"Mostrando página {self.current_page + 1} de {self.total_pages}"
page_selection = f"Página {self.current_page + 1}"
return page_image, info_text, gr.update(value=page_selection)
return None, "Ya estás en la primera página", gr.update()
def next_page(self):
"""Ir a la página siguiente"""
if self.current_doc is None:
return None, "No hay PDF cargado", gr.update()
if self.current_page < self.total_pages - 1:
self.current_page += 1
page_image = self.get_page_image(self.current_page)
info_text = f"Mostrando página {self.current_page + 1} de {self.total_pages}"
page_selection = f"Página {self.current_page + 1}"
return page_image, info_text, gr.update(value=page_selection)
return None, "Ya estás en la última página", gr.update()
# Crear instancia del visualizador
pdf_viewer = PDFViewer()
# Crear la interfaz de Gradio
with gr.Blocks(title="Visualizador PDF", theme=gr.themes.Soft()) as demo:
gr.Markdown("# 📄 Visualizador de PDF con Navegación")
gr.Markdown("Sube un archivo PDF y navega entre sus páginas usando los controles.")
with gr.Row():
with gr.Column(scale=1):
# Cargar archivo
pdf_input = gr.File(
label="Seleccionar archivo PDF",
file_types=[".pdf"],
type="filepath"
)
# Información del PDF
info_text = gr.Textbox(
label="Información",
value="No hay PDF cargado",
interactive=False
)
# Selector de páginas
page_selector = gr.Dropdown(
label="Seleccionar página",
choices=[],
visible=False
)
# Controles de navegación
with gr.Row(visible=False) as nav_controls:
prev_btn = gr.Button("⬅️ Anterior", size="sm")
next_btn = gr.Button("➡️ Siguiente", size="sm")
with gr.Column(scale=3):
# Visor de imagen
pdf_image = gr.Image(
label="Vista del PDF",
show_label=False,
container=True,
height=600
)
# Eventos
pdf_input.change(
pdf_viewer.load_pdf,
inputs=[pdf_input],
outputs=[pdf_image, info_text, page_selector, nav_controls]
)
page_selector.change(
pdf_viewer.navigate_to_page,
inputs=[page_selector],
outputs=[pdf_image, info_text]
)
prev_btn.click(
pdf_viewer.prev_page,
outputs=[pdf_image, info_text, page_selector]
)
next_btn.click(
pdf_viewer.next_page,
outputs=[pdf_image, info_text, page_selector]
)
# Lanzar la aplicación
if __name__ == "__main__":
demo.launch(share=True, debug=True)