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()