URI: 
       crop.py - bookcrop - Miscellaneous tools for digitizing books
  HTML git clone git://lumidify.org/bookcrop.git (fast, but not encrypted)
  HTML git clone https://lumidify.org/bookcrop.git (encrypted, but very slow)
  HTML git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/bookcrop.git (over tor)
   DIR Log
   DIR Files
   DIR Refs
   DIR README
       ---
       crop.py (5185B)
       ---
            1 #!/usr/bin/env python3
            2 
            3 # WARNING: CRAP CODE!!!
            4 # just generate list filled with None in beginning
            5 
            6 import sys
            7 import tkinter
            8 from PIL import ImageTk, Image
            9 
           10 if len(sys.argv) < 2:
           11         print("No images specified")
           12         sys.exit(1)
           13 
           14 cur_img = 1
           15 
           16 dragging = False
           17 dragging_rect = False
           18 x_orig = 0
           19 y_orig = 0
           20 x_new = 0
           21 y_new = 0
           22 x_grab = 0
           23 y_grab = 0
           24 x_drag_offset = 0
           25 y_drag_offset = 0
           26 
           27 # First None is ignored since cur_img is always one ahead (first arg is script name)
           28 coords = [None, None]
           29 img_sizes = [None]
           30 
           31 def rect_intersect(x1, y1, x2, y2, x_point, y_point):
           32         if x1 > x2:
           33                 tmp = x1
           34                 x1 = x2
           35                 x2 = tmp
           36         if y1 > y2:
           37                 tmp = y1
           38                 y1 = y2
           39                 y2 = tmp
           40         return x1 <= x_point <= x2 and y1 <= y_point <= y2
           41 
           42 def press(event):
           43         global dragging, dragging_rect, x_orig, y_orig, x_grab, y_grab, x_new, y_new, x_drag_offset, y_drag_offset
           44         if abs(x_orig - event.x) < 15 and abs(y_orig - event.y) < 15:
           45                 dragging = True
           46                 x_drag_offset = x_orig - event.x
           47                 y_drag_offset = y_orig - event.y
           48                 x_orig = x_new
           49                 y_orig = y_new
           50                 x_new = event.x
           51                 y_new = event.y
           52         elif abs(x_new - event.x) < 15 and abs(y_new - event.y) < 15:
           53                 dragging = True
           54                 x_drag_offset = x_new - event.x
           55                 y_drag_offset = y_new - event.y
           56         elif rect_intersect(x_orig, y_orig, x_new, y_new, event.x, event.y):
           57                 dragging_rect = True
           58                 x_grab = event.x
           59                 y_grab = event.y
           60         else:
           61                 dragging = True
           62                 x_orig = event.x
           63                 y_orig = event.y
           64                 x_drag_offset = 0
           65                 y_drag_offset = 0
           66 
           67 def motion(event):
           68         global dragging, dragging_rect, x_orig, y_orig, x_new, y_new, x_grab, y_grab
           69         if dragging:
           70                 x_new = event.x + x_drag_offset
           71                 y_new = event.y + y_drag_offset
           72         elif dragging_rect:
           73                 x_delta = event.x - x_grab
           74                 y_delta = event.y - y_grab
           75                 x_grab = event.x
           76                 y_grab = event.y
           77                 x_orig += x_delta
           78                 x_new += x_delta
           79                 y_orig += y_delta
           80                 y_new += y_delta
           81         event.widget.create_rectangle(x_orig, y_orig, x_new, y_new)
           82 
           83 def release(event):
           84         global dragging, dragging_rect, tkimg, x_orig, y_orig, x_new, y_new
           85         if dragging:
           86                 dragging = False
           87                 x_new = event.x + x_drag_offset
           88                 y_new = event.y + y_drag_offset
           89         elif dragging_rect:
           90                 dragging_rect = False
           91                 x_delta = event.x - x_grab
           92                 y_delta = event.y - y_grab
           93                 x_orig += x_delta
           94                 x_new += x_delta
           95                 y_orig += y_delta
           96                 y_new += y_delta
           97         event.widget.create_image(0, 0, anchor=tkinter.NW, image=tkimg)
           98         event.widget.create_rectangle(x_orig, y_orig, x_new, y_new)
           99 
          100 def print_exit(*args):
          101         global cur_img
          102         cur_img = -1 
          103         for c in coords:
          104                 cur_img += 1
          105                 if c == None:
          106                         continue
          107                 x_scale = img_sizes[cur_img][0] / img_sizes[cur_img][2]
          108                 y_scale = img_sizes[cur_img][1] / img_sizes[cur_img][3]
          109                 x1 = min(c[0], c[2])
          110                 x2 = max(c[0], c[2])
          111                 y1 = min(c[1], c[3])
          112                 y2 = max(c[1], c[3])
          113                 w_crop = x_scale * (x2 - x1);
          114                 h_crop = y_scale * (y2 - y1);
          115                 x_offset = x_scale * x1;
          116                 y_offset = y_scale * y1;
          117                 print("mogrify -crop " + str(round(w_crop)) + "x" + str(round(h_crop)) + "+" + str(round(x_offset)) + "+" + str(round(y_offset)) + " " + sys.argv[cur_img]);
          118         root.destroy()
          119         sys.exit(0)
          120 
          121 def left(event):
          122         global cur_img, x_orig, y_orig, x_new, y_new
          123         if cur_img <= 1:
          124                 return
          125         cur_img -= 1
          126         load_img()
          127         if coords[cur_img] != None:
          128                 x_orig, y_orig, x_new, y_new = coords[cur_img]
          129                 canvas.create_rectangle(*coords[cur_img])
          130         else:
          131                 x_orig = y_orig = x_new = y_new = 0
          132 
          133 def right(event):
          134         global cur_img, x_orig, y_orig, x_new, y_new
          135         if cur_img >= len(sys.argv) - 1:
          136                 return
          137         cur_img += 1
          138         load_img()
          139         if cur_img >= len(coords):
          140                 coords.append(None)
          141         if coords[cur_img] != None:
          142                 x_orig, y_orig, x_new, y_new = coords[cur_img]
          143                 canvas.create_rectangle(*coords[cur_img])
          144         else:
          145                 x_orig = y_orig = x_new = y_new = 0
          146 
          147 def return_event(event):
          148         global cur_img, x_orig, x_new, y_orig, y_new
          149         if x_orig < 0:
          150                 x_orig = 0
          151         if x_new < 0:
          152                 x_new = 0
          153         if x_orig > w_scaled:
          154                 x_orig = w_scaled
          155         if x_new > w_scaled:
          156                 x_new = w_scaled
          157         if y_orig < 0:
          158                 y_orig = 0
          159         if y_new < 0:
          160                 y_new = 0
          161         if y_orig > h_scaled:
          162                 y_orig = h_scaled
          163         if y_new > h_scaled:
          164                 y_new = h_scaled
          165         if x_orig == x_new or y_orig == y_new:
          166                 return
          167         coords[cur_img] = [x_orig, y_orig, x_new, y_new]
          168         if cur_img >= len(sys.argv) - 1:
          169                 return
          170         cur_img += 1
          171         load_img()
          172         if cur_img >= len(coords):
          173                 coords.append(None)
          174         if coords[cur_img] != None:
          175                 x_orig, y_orig, x_new, y_new = coords[cur_img]
          176                 canvas.create_rectangle(*coords[cur_img])
          177         else:
          178                 canvas.create_rectangle(*coords[cur_img-1])
          179 
          180 def load_img():
          181         global img, w, h, w_scaled, h_scaled, tkimg
          182         img = Image.open(sys.argv[cur_img])
          183         w, h = img.size
          184         img.thumbnail((1278, 760), Image.ANTIALIAS)
          185         w_scaled, h_scaled = img.size
          186         if cur_img >= len(img_sizes):
          187                 img_sizes.append([w, h, w_scaled, h_scaled])
          188         tkimg = ImageTk.PhotoImage(img);
          189         canvas.create_image(0, 0, anchor=tkinter.NW, image=tkimg)
          190         root.title(sys.argv[cur_img]);
          191 
          192 root = tkinter.Tk()
          193 
          194 canvas = tkinter.Canvas(root, width=1278, height=760)
          195 canvas.pack()
          196 canvas.bind('<B1-Motion>', motion)
          197 canvas.bind('<ButtonRelease-1>', release)
          198 canvas.bind('<ButtonPress-1>', press)
          199 img, w, h, w_scaled, h_scaled, tkimg = 0, 0, 0, 0, 0, 0
          200 load_img()
          201 root.bind('<Return>', return_event)
          202 root.bind('<Left>', left)
          203 root.bind('<Right>', right)
          204 root.bind('<Escape>', print_exit)
          205 tkinter.mainloop()