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.") | |