Skip to content

Commit 3dc84a4

Browse files
committed
Add image conversion functionality for PDF pages and update UI modes
1 parent 581d168 commit 3dc84a4

File tree

2 files changed

+95
-1
lines changed

2 files changed

+95
-1
lines changed

main.py

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from PyQt6.QtCore import Qt
1010
from PyQt6.QtGui import QFont
1111
from PyPDF2 import PdfReader, PdfWriter
12+
from pdf2image import convert_from_path
1213

1314

1415
class Mode:
@@ -130,6 +131,61 @@ def split_pdf(input_path, chunk_size, output_path):
130131
return message
131132

132133

134+
def convert_to_images(input_path, page_numbers, output_path):
135+
"""Convert specified PDF pages to images."""
136+
reader = PdfReader(input_path)
137+
total_pages = len(reader.pages)
138+
139+
valid_pages = []
140+
invalid_pages = []
141+
142+
# Validate page numbers
143+
for page_num in page_numbers:
144+
if 1 <= page_num <= total_pages:
145+
valid_pages.append(page_num)
146+
else:
147+
invalid_pages.append(page_num)
148+
149+
if not valid_pages:
150+
raise ValueError("No valid pages to convert to images.")
151+
152+
# Determine output naming
153+
output_file = Path(output_path)
154+
base_name = output_file.stem
155+
output_dir = output_file.parent
156+
157+
# Ensure output directory exists
158+
output_dir.mkdir(parents=True, exist_ok=True)
159+
160+
created_files = []
161+
162+
# Convert pages to images
163+
# pdf2image uses 1-based indexing, matching our page_numbers
164+
images = convert_from_path(input_path, first_page=min(valid_pages),
165+
last_page=max(valid_pages))
166+
167+
for page_num in valid_pages:
168+
# Get the corresponding image from the converted range
169+
image_index = page_num - min(valid_pages)
170+
if image_index < len(images):
171+
image = images[image_index]
172+
173+
# Generate output filename
174+
output_filename = output_dir / f"{base_name}_page{page_num}.png"
175+
image.save(str(output_filename), "PNG")
176+
created_files.append(str(output_filename))
177+
178+
num_images = len(created_files)
179+
message = f"Successfully converted {num_images} page{'s' if num_images > 1 else ''} to image{'s' if num_images > 1 else ''}"
180+
181+
if invalid_pages:
182+
message += f"\n\nSkipped invalid pages: {invalid_pages} (PDF has {total_pages} pages)"
183+
184+
message += f"\n\nCreated {num_images} PNG image{'s' if num_images > 1 else ''} in:\n{output_dir}"
185+
186+
return message
187+
188+
133189
class PDFPageSelectorApp(QMainWindow):
134190
def __init__(self):
135191
super().__init__()
@@ -155,6 +211,15 @@ def __init__(self):
155211
help_text="Number of pages per file (greater than 0)",
156212
process_func=self._process_split,
157213
output_suffix="_split"
214+
),
215+
Mode(
216+
name="image",
217+
display_name="Image",
218+
section_title="Page Ranges",
219+
placeholder="e.g., 1-3,5,6-9,11",
220+
help_text="Examples: 1-3,5,6-9,11 or 1,3,5 or 10-20",
221+
process_func=self._process_image,
222+
output_suffix="_images"
158223
)
159224
]
160225

@@ -196,7 +261,7 @@ def init_ui(self):
196261
layout.addWidget(self._create_output_section())
197262

198263
# Process button
199-
self.process_button = QPushButton("Create Trimmed PDF")
264+
self.process_button = QPushButton("Execute")
200265
self.process_button.setMinimumHeight(40)
201266
self.process_button.setFont(QFont("", 11, QFont.Weight.Bold))
202267
self.process_button.clicked.connect(self.process_pdf)
@@ -421,6 +486,35 @@ def _process_split(self, chunk_input):
421486
message = split_pdf(self.input_path, chunk_size, self.output_path)
422487
self._show_success(message)
423488

489+
def _process_image(self, page_input):
490+
"""Process PDF in image mode."""
491+
self._ensure_output_path()
492+
try:
493+
page_numbers = parse_page_ranges(page_input)
494+
except (ValueError, AttributeError) as e:
495+
raise ValueError(f"Invalid page format:\n{str(e)}")
496+
497+
# Check if any output files would be overwritten
498+
if self.output_path:
499+
output_file = Path(self.output_path)
500+
base_name = output_file.stem
501+
output_dir = output_file.parent
502+
503+
# Check if any of the image files exist
504+
files_exist = False
505+
for page_num in page_numbers:
506+
image_file = output_dir / f"{base_name}_page{page_num}.png"
507+
if image_file.exists():
508+
files_exist = True
509+
break
510+
511+
if files_exist:
512+
if not self._confirm_overwrite():
513+
return
514+
515+
message = convert_to_images(self.input_path, page_numbers, self.output_path)
516+
self._show_success(message)
517+
424518
def _confirm_overwrite(self):
425519
"""Ask user to confirm file overwrite."""
426520
reply = QMessageBox.question(

requirements.txt

70 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)