removed carriage returns X1 master
authorArcnilya <jonathan.magnusson@kau.se>
Wed, 2 Feb 2022 12:54:21 +0000 (13:54 +0100)
committerArcnilya <jonathan.magnusson@kau.se>
Wed, 2 Feb 2022 12:54:21 +0000 (13:54 +0100)
hentai-cropper.py

index 69fd17a6620b4c01074479446874a241f639a789..2bc3775cc275d6b191501920a3ce402db2e5bc51 100644 (file)
-# This application is based on:\r
-# https://github.com/foobar167/junkyard/blob/master/zoom_advanced.py\r
-\r
-# -*- coding: utf-8 -*-\r
-# Advanced zoom example. Like in Google Maps.\r
-# It zooms only a tile, but not the whole image. So the zoomed tile occupies\r
-# constant memory and not cram it with a huge resized image for the large zooms.\r
-\r
-import tkinter as tk\r
-from tkinter import ttk\r
-from PIL import Image, ImageTk\r
-import os\r
-import argparse\r
-# sudo apt-get install python3-pil.imagetk\r
-\r
-parser = argparse.ArgumentParser()\r
-parser.add_argument('-i', '--input', type=str, required=True, help="input directory")\r
-parser.add_argument('-o', '--output', type=str, default="", help="output directory")\r
-\r
-\r
-class AutoScrollbar(ttk.Scrollbar):\r
-    def set(self, lo, hi):\r
-        self.grid_remove()\r
-\r
-    def pack(self, **kw):\r
-        raise tk.TclError('Cannot use pack with this widget')\r
-\r
-    def place(self, **kw):\r
-        raise tk.TclError('Cannot use place with this widget')\r
-\r
-\r
-def load_paths(in_path, out_path):\r
-    in_list = []\r
-    out_list = []\r
-    for fname in os.listdir(in_path):\r
-        in_list.append(os.path.join(in_path, fname))\r
-        out_list.append(os.path.join(out_path, fname.split('.')[0] + "-crop.png"))\r
-    return in_list, out_list\r
-\r
-\r
-class ZoomAdvanced(ttk.Frame):\r
-    # Advanced zoom of the image\r
-    def __init__(self, mainframe, input, output):\r
-        # Initialize the main Frame\r
-        ttk.Frame.__init__(self, master=mainframe)\r
-        # Vertical and horizontal scrollbars for canvas\r
-        vbar = AutoScrollbar(self.master, orient='vertical')\r
-        hbar = AutoScrollbar(self.master, orient='horizontal')\r
-        vbar.grid(row=0, column=1, sticky='ns')\r
-        hbar.grid(row=1, column=0, sticky='we')\r
-        # Create canvas and put image on it\r
-        self.canvas = tk.Canvas(self.master, highlightthickness=0,\r
-                                xscrollcommand=hbar.set, yscrollcommand=vbar.set)\r
-        self.canvas.grid(row=0, column=0, sticky='nswe')\r
-        self.canvas.update()  # wait till canvas is created\r
-        vbar.configure(command=self.scroll_y)  # bind scrollbars to the canvas\r
-        hbar.configure(command=self.scroll_x)\r
-        # Make the canvas expandable\r
-        self.master.rowconfigure(0, weight=1)\r
-        self.master.columnconfigure(0, weight=1)\r
-        # Bind events to the Canvas\r
-        self.canvas.bind('<Configure>', self.show_image)  # canvas is resized\r
-        self.canvas.bind('<ButtonPress-1>', self.move_from)\r
-        self.canvas.bind('<B1-Motion>',     self.move_to)\r
-        self.canvas.bind('<MouseWheel>', self.wheel)  # with Windows and MacOS, but not Linux\r
-        self.canvas.bind('<Button-5>',   self.wheel)  # only with Linux, wheel scroll down\r
-        self.canvas.bind('<Button-4>',   self.wheel)  # only with Linux, wheel scroll up\r
-        self.canvas.bind_all('<Return>', self.save_img)\r
-\r
-        self.in_paths, self.out_paths = load_paths(input, output)\r
-        self.counter = 0\r
-        self.image = None\r
-        self.destination = None\r
-        self.width = 0\r
-        self.height = 0\r
-        self.imscale = 1.0\r
-        self.delta = 1.1\r
-        self.container = None\r
-        self.img = None\r
-        # open first image\r
-        self.load_img()\r
-        self.show_image()\r
-\r
-    def load_img(self):\r
-        while os.path.exists(self.out_paths[self.counter]):\r
-            self.counter += 1\r
-        self.image = Image.open(self.in_paths[self.counter])\r
-        self.destination = self.out_paths[self.counter]\r
-        print(str(os.path.basename(self.in_paths[self.counter])))\r
-        self.master.title(os.path.basename(self.in_paths[self.counter]))\r
-        self.width, self.height = self.image.size\r
-        self.imscale = 1.0  # scale for the canvas image\r
-        # Put image into container rectangle and use it to set proper coordinates to the image\r
-        self.container = self.canvas.create_rectangle(0, 0, self.width, self.height, width=0)\r
-        self.img = None\r
-\r
-    def save_img(self, event):\r
-        print("Saving cropped image...")\r
-        self.img.save(self.destination)\r
-        self.counter += 1\r
-        if self.counter < len(self.in_paths):\r
-            print("Loading new image...")\r
-            self.load_img()\r
-            self.show_image()\r
-        else:\r
-            print("Exiting...")\r
-            self.master.destroy()\r
-\r
-    def scroll_y(self, *args, **kwargs):\r
-        # Scroll canvas vertically and redraw the image\r
-        self.canvas.yview(*args, **kwargs)  # scroll vertically\r
-        self.show_image()  # redraw the image\r
-\r
-    def scroll_x(self, *args, **kwargs):\r
-        # Scroll canvas horizontally and redraw the image\r
-        self.canvas.xview(*args, **kwargs)  # scroll horizontally\r
-        self.show_image()  # redraw the image\r
-\r
-    def move_from(self, event):\r
-        # Remember previous coordinates for scrolling with the mouse\r
-        self.canvas.scan_mark(event.x, event.y)\r
-\r
-    def move_to(self, event):\r
-        # Drag (move) canvas to the new position\r
-        self.canvas.scan_dragto(event.x, event.y, gain=1)\r
-        self.show_image()  # redraw the image\r
-\r
-    def wheel(self, event):\r
-        # Zoom with mouse wheel\r
-        x = self.canvas.canvasx(event.x)\r
-        y = self.canvas.canvasy(event.y)\r
-        bbox = self.canvas.bbox(self.container)  # get image area\r
-        if bbox[0] < x < bbox[2] and bbox[1] < y < bbox[3]:\r
-            pass  # Ok! Inside the image\r
-        else:\r
-            return  # zoom only inside image area\r
-        scale = 1.0\r
-        # Respond to Linux (event.num) or Windows (event.delta) wheel event\r
-        if event.num == 5 or event.delta == -120:  # scroll down\r
-            i = min(self.width, self.height)\r
-            if int(i * self.imscale) < 30:\r
-                return  # image is less than 30 pixels\r
-            self.imscale /= self.delta\r
-            scale /= self.delta\r
-        if event.num == 4 or event.delta == 120:  # scroll up\r
-            i = min(self.canvas.winfo_width(), self.canvas.winfo_height())\r
-            if i < self.imscale:\r
-                return  # 1 pixel is bigger than the visible area\r
-            self.imscale *= self.delta\r
-            scale *= self.delta\r
-        self.canvas.scale('all', x, y, scale, scale)  # rescale all canvas objects\r
-        self.show_image()\r
-\r
-    def show_image(self, event=None):\r
-        # Show image on the Canvas\r
-        bbox1 = self.canvas.bbox(self.container)  # get image area\r
-        # Remove 1 pixel shift at the sides of the bbox1\r
-        bbox1 = (bbox1[0] + 1, bbox1[1] + 1, bbox1[2] - 1, bbox1[3] - 1)\r
-        bbox2 = (self.canvas.canvasx(0),  # get visible area of the canvas\r
-                 self.canvas.canvasy(0),\r
-                 self.canvas.canvasx(self.canvas.winfo_width()),\r
-                 self.canvas.canvasy(self.canvas.winfo_height()))\r
-        bbox = [min(bbox1[0], bbox2[0]), min(bbox1[1], bbox2[1]),  # get scroll region box\r
-                max(bbox1[2], bbox2[2]), max(bbox1[3], bbox2[3])]\r
-        if bbox[0] == bbox2[0] and bbox[2] == bbox2[2]:  # whole image in the visible area\r
-            bbox[0] = bbox1[0]\r
-            bbox[2] = bbox1[2]\r
-        if bbox[1] == bbox2[1] and bbox[3] == bbox2[3]:  # whole image in the visible area\r
-            bbox[1] = bbox1[1]\r
-            bbox[3] = bbox1[3]\r
-        self.canvas.configure(scrollregion=bbox)  # set scroll region\r
-        x1 = max(bbox2[0] - bbox1[0], 0)  # get coordinates (x1,y1,x2,y2) of the image tile\r
-        y1 = max(bbox2[1] - bbox1[1], 0)\r
-        x2 = min(bbox2[2], bbox1[2]) - bbox1[0]\r
-        y2 = min(bbox2[3], bbox1[3]) - bbox1[1]\r
-        if int(x2 - x1) > 0 and int(y2 - y1) > 0:  # show image if it in the visible area\r
-            x = min(int(x2 / self.imscale), self.width)   # sometimes it is larger on 1 pixel...\r
-            y = min(int(y2 / self.imscale), self.height)  # ...and sometimes not\r
-            image = self.image.crop((int(x1 / self.imscale), int(y1 / self.imscale), x, y))\r
-            imagetk = ImageTk.PhotoImage(image.resize((int(x2 - x1), int(y2 - y1))))\r
-            imageid = self.canvas.create_image(max(bbox2[0], bbox1[0]), max(bbox2[1], bbox1[1]),\r
-                                               anchor='nw', image=imagetk)\r
-            self.canvas.lower(imageid)  # set image into background\r
-            self.canvas.imagetk = imagetk  # keep an extra reference to prevent garbage-collection\r
-            self.img = image.resize((int(x2 - x1), int(y2 - y1)))\r
-\r
-\r
-root = tk.Tk()\r
-root.geometry("500x500")\r
-root.resizable(width=False, height=False)\r
-args = parser.parse_args()\r
-app = ZoomAdvanced(root, args.input, args.output if args.output != "" else args.input)\r
-root.mainloop()\r
+# This application is based on:
+# https://github.com/foobar167/junkyard/blob/master/zoom_advanced.py
+
+# -*- coding: utf-8 -*-
+# Advanced zoom example. Like in Google Maps.
+# It zooms only a tile, but not the whole image. So the zoomed tile occupies
+# constant memory and not cram it with a huge resized image for the large zooms.
+
+import tkinter as tk
+from tkinter import ttk
+from PIL import Image, ImageTk
+import os
+import argparse
+# sudo apt-get install python3-pil.imagetk
+
+parser = argparse.ArgumentParser()
+parser.add_argument('-i', '--input', type=str, required=True, help="input directory")
+parser.add_argument('-o', '--output', type=str, default="", help="output directory")
+
+
+class AutoScrollbar(ttk.Scrollbar):
+    def set(self, lo, hi):
+        self.grid_remove()
+
+    def pack(self, **kw):
+        raise tk.TclError('Cannot use pack with this widget')
+
+    def place(self, **kw):
+        raise tk.TclError('Cannot use place with this widget')
+
+
+def load_paths(in_path, out_path):
+    in_list = []
+    out_list = []
+    for fname in os.listdir(in_path):
+        in_list.append(os.path.join(in_path, fname))
+        out_list.append(os.path.join(out_path, fname.split('.')[0] + "-crop.png"))
+    return in_list, out_list
+
+
+class ZoomAdvanced(ttk.Frame):
+    # Advanced zoom of the image
+    def __init__(self, mainframe, input, output):
+        # Initialize the main Frame
+        ttk.Frame.__init__(self, master=mainframe)
+        # Vertical and horizontal scrollbars for canvas
+        vbar = AutoScrollbar(self.master, orient='vertical')
+        hbar = AutoScrollbar(self.master, orient='horizontal')
+        vbar.grid(row=0, column=1, sticky='ns')
+        hbar.grid(row=1, column=0, sticky='we')
+        # Create canvas and put image on it
+        self.canvas = tk.Canvas(self.master, highlightthickness=0,
+                                xscrollcommand=hbar.set, yscrollcommand=vbar.set)
+        self.canvas.grid(row=0, column=0, sticky='nswe')
+        self.canvas.update()  # wait till canvas is created
+        vbar.configure(command=self.scroll_y)  # bind scrollbars to the canvas
+        hbar.configure(command=self.scroll_x)
+        # Make the canvas expandable
+        self.master.rowconfigure(0, weight=1)
+        self.master.columnconfigure(0, weight=1)
+        # Bind events to the Canvas
+        self.canvas.bind('<Configure>', self.show_image)  # canvas is resized
+        self.canvas.bind('<ButtonPress-1>', self.move_from)
+        self.canvas.bind('<B1-Motion>',     self.move_to)
+        self.canvas.bind('<MouseWheel>', self.wheel)  # with Windows and MacOS, but not Linux
+        self.canvas.bind('<Button-5>',   self.wheel)  # only with Linux, wheel scroll down
+        self.canvas.bind('<Button-4>',   self.wheel)  # only with Linux, wheel scroll up
+        self.canvas.bind_all('<Return>', self.save_img)
+
+        self.in_paths, self.out_paths = load_paths(input, output)
+        self.counter = 0
+        self.image = None
+        self.destination = None
+        self.width = 0
+        self.height = 0
+        self.imscale = 1.0
+        self.delta = 1.1
+        self.container = None
+        self.img = None
+        # open first image
+        self.load_img()
+        self.show_image()
+
+    def load_img(self):
+        while os.path.exists(self.out_paths[self.counter]):
+            self.counter += 1
+        self.image = Image.open(self.in_paths[self.counter])
+        self.destination = self.out_paths[self.counter]
+        print(str(os.path.basename(self.in_paths[self.counter])))
+        self.master.title(os.path.basename(self.in_paths[self.counter]))
+        self.width, self.height = self.image.size
+        self.imscale = 1.0  # scale for the canvas image
+        # Put image into container rectangle and use it to set proper coordinates to the image
+        self.container = self.canvas.create_rectangle(0, 0, self.width, self.height, width=0)
+        self.img = None
+
+    def save_img(self, event):
+        print("Saving cropped image...")
+        self.img.save(self.destination)
+        self.counter += 1
+        if self.counter < len(self.in_paths):
+            print("Loading new image...")
+            self.load_img()
+            self.show_image()
+        else:
+            print("Exiting...")
+            self.master.destroy()
+
+    def scroll_y(self, *args, **kwargs):
+        # Scroll canvas vertically and redraw the image
+        self.canvas.yview(*args, **kwargs)  # scroll vertically
+        self.show_image()  # redraw the image
+
+    def scroll_x(self, *args, **kwargs):
+        # Scroll canvas horizontally and redraw the image
+        self.canvas.xview(*args, **kwargs)  # scroll horizontally
+        self.show_image()  # redraw the image
+
+    def move_from(self, event):
+        # Remember previous coordinates for scrolling with the mouse
+        self.canvas.scan_mark(event.x, event.y)
+
+    def move_to(self, event):
+        # Drag (move) canvas to the new position
+        self.canvas.scan_dragto(event.x, event.y, gain=1)
+        self.show_image()  # redraw the image
+
+    def wheel(self, event):
+        # Zoom with mouse wheel
+        x = self.canvas.canvasx(event.x)
+        y = self.canvas.canvasy(event.y)
+        bbox = self.canvas.bbox(self.container)  # get image area
+        if bbox[0] < x < bbox[2] and bbox[1] < y < bbox[3]:
+            pass  # Ok! Inside the image
+        else:
+            return  # zoom only inside image area
+        scale = 1.0
+        # Respond to Linux (event.num) or Windows (event.delta) wheel event
+        if event.num == 5 or event.delta == -120:  # scroll down
+            i = min(self.width, self.height)
+            if int(i * self.imscale) < 30:
+                return  # image is less than 30 pixels
+            self.imscale /= self.delta
+            scale /= self.delta
+        if event.num == 4 or event.delta == 120:  # scroll up
+            i = min(self.canvas.winfo_width(), self.canvas.winfo_height())
+            if i < self.imscale:
+                return  # 1 pixel is bigger than the visible area
+            self.imscale *= self.delta
+            scale *= self.delta
+        self.canvas.scale('all', x, y, scale, scale)  # rescale all canvas objects
+        self.show_image()
+
+    def show_image(self, event=None):
+        # Show image on the Canvas
+        bbox1 = self.canvas.bbox(self.container)  # get image area
+        # Remove 1 pixel shift at the sides of the bbox1
+        bbox1 = (bbox1[0] + 1, bbox1[1] + 1, bbox1[2] - 1, bbox1[3] - 1)
+        bbox2 = (self.canvas.canvasx(0),  # get visible area of the canvas
+                 self.canvas.canvasy(0),
+                 self.canvas.canvasx(self.canvas.winfo_width()),
+                 self.canvas.canvasy(self.canvas.winfo_height()))
+        bbox = [min(bbox1[0], bbox2[0]), min(bbox1[1], bbox2[1]),  # get scroll region box
+                max(bbox1[2], bbox2[2]), max(bbox1[3], bbox2[3])]
+        if bbox[0] == bbox2[0] and bbox[2] == bbox2[2]:  # whole image in the visible area
+            bbox[0] = bbox1[0]
+            bbox[2] = bbox1[2]
+        if bbox[1] == bbox2[1] and bbox[3] == bbox2[3]:  # whole image in the visible area
+            bbox[1] = bbox1[1]
+            bbox[3] = bbox1[3]
+        self.canvas.configure(scrollregion=bbox)  # set scroll region
+        x1 = max(bbox2[0] - bbox1[0], 0)  # get coordinates (x1,y1,x2,y2) of the image tile
+        y1 = max(bbox2[1] - bbox1[1], 0)
+        x2 = min(bbox2[2], bbox1[2]) - bbox1[0]
+        y2 = min(bbox2[3], bbox1[3]) - bbox1[1]
+        if int(x2 - x1) > 0 and int(y2 - y1) > 0:  # show image if it in the visible area
+            x = min(int(x2 / self.imscale), self.width)   # sometimes it is larger on 1 pixel...
+            y = min(int(y2 / self.imscale), self.height)  # ...and sometimes not
+            image = self.image.crop((int(x1 / self.imscale), int(y1 / self.imscale), x, y))
+            imagetk = ImageTk.PhotoImage(image.resize((int(x2 - x1), int(y2 - y1))))
+            imageid = self.canvas.create_image(max(bbox2[0], bbox1[0]), max(bbox2[1], bbox1[1]),
+                                               anchor='nw', image=imagetk)
+            self.canvas.lower(imageid)  # set image into background
+            self.canvas.imagetk = imagetk  # keep an extra reference to prevent garbage-collection
+            self.img = image.resize((int(x2 - x1), int(y2 - y1)))
+
+
+root = tk.Tk()
+root.geometry("500x500")
+root.resizable(width=False, height=False)
+args = parser.parse_args()
+app = ZoomAdvanced(root, args.input, args.output if args.output != "" else args.input)
+root.mainloop()