This is a simple program designed to extract a PDF from the Taghche application.
For a step-by-step guide on how to use this program, you can watch the tutorial here.
This is a simple program designed to extract a PDF from the Taghche application.
For a step-by-step guide on how to use this program, you can watch the tutorial here.
import tkinter as tk | |
import pyautogui | |
import time | |
from tkinter import messagebox | |
import os | |
from PIL import Image, ImageEnhance | |
import cv2 | |
class SnippingTool: | |
def __init__(self, root, npages=642): | |
self.root = root | |
self.root.geometry('300x200') | |
self.root.title('Snipping Tool') | |
self.region_button = tk.Button(self.root, text='Select Region', command=self.start_snipping_region) | |
self.region_button.pack(pady=10) | |
self.point_button = tk.Button(self.root, text='Select Point', command=self.start_snipping_point) | |
self.point_button.pack(pady=10) | |
self.confirm_button = tk.Button(self.root, text='Confirm & Process', command=self.confirm_selection) | |
self.confirm_button.pack(pady=10) | |
self.npages=npages | |
self.region = None | |
self.point = None | |
self.app_title = 'طاقچه' # Replace with the actual title of the application | |
def start_snipping_region(self): | |
self.root.withdraw() # Hide the main window | |
self.snip_window = tk.Toplevel(self.root) | |
self.snip_window.attributes("-fullscreen", True) | |
self.snip_window.attributes("-alpha", 0.3) # Transparency | |
self.canvas = tk.Canvas(self.snip_window, cursor="cross") | |
self.canvas.pack(fill=tk.BOTH, expand=tk.TRUE) | |
self.start_x = None | |
self.start_y = None | |
self.rect = None | |
self.canvas.bind("<ButtonPress-1>", self.on_button_press) | |
self.canvas.bind("<B1-Motion>", self.on_mouse_drag) | |
self.canvas.bind("<ButtonRelease-1>", self.on_button_release_region) | |
def start_snipping_point(self): | |
self.root.withdraw() # Hide the main window | |
self.snip_window = tk.Toplevel(self.root) | |
self.snip_window.attributes("-fullscreen", True) | |
self.snip_window.attributes("-alpha", 0.3) # Transparency | |
self.canvas = tk.Canvas(self.snip_window, cursor="cross") | |
self.canvas.pack(fill=tk.BOTH, expand=tk.TRUE) | |
self.canvas.bind("<ButtonPress-1>", self.on_button_press_point) | |
def on_button_press(self, event): | |
self.start_x = self.canvas.canvasx(event.x) | |
self.start_y = self.canvas.canvasy(event.y) | |
self.rect = self.canvas.create_rectangle(self.start_x, self.start_y, self.start_x, self.start_y, outline='red', width=2) | |
def on_mouse_drag(self, event): | |
curX = self.canvas.canvasx(event.x) | |
curY = self.canvas.canvasy(event.y) | |
self.canvas.coords(self.rect, self.start_x, self.start_y, curX, curY) | |
def on_button_release_region(self, event): | |
end_x = self.canvas.canvasx(event.x) | |
end_y = self.canvas.canvasy(event.y) | |
self.region = (self.start_x, self.start_y, end_x - self.start_x, end_y - self.start_y) | |
self.snip_window.destroy() | |
self.root.deiconify() # Show the main window | |
print("Selected region:", self.region) | |
def on_button_press_point(self, event): | |
self.point = (self.canvas.canvasx(event.x), self.canvas.canvasy(event.y)) | |
self.snip_window.destroy() | |
self.root.deiconify() # Show the main window | |
print("Selected point:", self.point) | |
def confirm_selection(self): | |
if self.region and self.point: | |
print("Confirmed region:", self.region) | |
print("Confirmed point:", self.point) | |
self.process_selection(self.region, self.point) | |
self.root.quit() # Close the main window | |
else: | |
messagebox.showwarning("Incomplete Selection", "Please select both region and point before confirming.") | |
def process_selection(self, region, point): | |
print("Processing with region:", region, "and point:", point) | |
self.activate_application() | |
for id in range(self.npages): | |
pyautogui.leftClick(self.point) | |
l = len(str(self.npages)) | |
for _ in range(l): | |
pyautogui.press('backspace') | |
for _ in range(l): | |
pyautogui.press('del') | |
pyautogui.write(str(id+1)) | |
pyautogui.press('enter') | |
time.sleep(0.3) | |
self.take_screenshot(f"tmp/screenshot_{id}.png", region) | |
# id=0 | |
# while id<self.npages: | |
# self.take_screenshot(f"tmp/screenshot_{id}.png", region) | |
# time.sleep(0.5) | |
# if id>0: | |
# img1 = cv2.imread(f"tmp/screenshot_{id-1}.png") | |
# img2 = cv2.imread(f"tmp/screenshot_{id}.png") | |
# if is_similar(img1,img2): | |
# os.remove(f"tmp/screenshot_{id}.png") | |
# id-=1 | |
# pyautogui.press('left') | |
# id+=1 | |
# #pyautogui.leftClick(point) | |
def take_screenshot(self, filename, region): | |
region = tuple(map(int, region)) # Convert region values to integers | |
self.activate_application() # Ensure the application is active | |
screenshot = pyautogui.screenshot(region=region) | |
screenshot.save(filename) | |
print(f"Screenshot saved to {filename}") | |
def activate_application(self): | |
current_window = pyautogui.getActiveWindow() | |
if current_window is None or self.app_title not in current_window.title: | |
try: | |
pyautogui.getWindowsWithTitle(self.app_title)[0].activate() | |
except IndexError: | |
print(f"Window with title '{self.app_title}' not found or not active.") | |
def run(self): | |
self.root.mainloop() | |
def enhance_image(input_image, output_image): | |
# Open the image file | |
img = Image.open(input_image) | |
# Enhance contrast to bring out details in black and white areas | |
enhancer = ImageEnhance.Contrast(img) | |
img = enhancer.enhance(1.5) # Adjust contrast more aggressively for clear text | |
# Enhance brightness slightly to brighten up dark areas without washing out white areas | |
enhancer = ImageEnhance.Brightness(img) | |
img = enhancer.enhance(1.2) # Adjust brightness conservatively | |
# Save the enhanced image | |
img.save(output_image) | |
print(f"Enhanced image saved as {output_image}") | |
def rotate_images_right(directory): | |
# Iterate through all files in the directory | |
for filename in os.listdir(directory): | |
if filename.endswith(".png") or filename.endswith(".jpg") or filename.endswith(".jpeg"): | |
# Open each image file | |
img_path = os.path.join(directory, filename) | |
img = Image.open(img_path) | |
# Rotate the image right (clockwise) | |
rotated_img = img.transpose(Image.ROTATE_270) | |
# Save the rotated image, overwriting the original | |
rotated_img.save(img_path) | |
print(f"Rotated and saved {filename} successfully.") | |
def concat_images_to_pdf(image_files, output_pdf): | |
# Sort the images by filename in ascending order | |
image_files.sort() | |
# Open the images | |
images = [Image.open(img).convert('RGB') for img in image_files] | |
# Save the images as a PDF | |
if images: | |
images[0].save(output_pdf, save_all=True, append_images=images[1:]) | |
print(f"PDF saved as {output_pdf}") | |
def get_image_files(directory): | |
image_extensions = ('.png', '.jpg', '.jpeg', '.bmp', '.gif', '.tiff') | |
return [os.path.join(directory, f) for f in os.listdir(directory) if f.lower().endswith(image_extensions)] | |
def is_similar(img1, img2): | |
return img1.shape==img2.shape and not(cv2.bitwise_xor(img1,img2).any()) | |
if __name__ == "__main__": | |
root = tk.Tk() | |
app = SnippingTool(root,npages=10) | |
app.run() | |
# rotate_images_right("tmp/") | |
for i,item in enumerate(os.listdir("tmp/")): | |
enhance_image("tmp/" + item, "tmp/" + item) | |
print(i,item) | |
image_files = get_image_files("tmp/") | |
if image_files: | |
concat_images_to_pdf(image_files, "book_name.pdf") | |
else: | |
print("No image files found in the specified directory.") | |