bookcrop

Miscellaneous tools for digitizing books
git clone git://lumidify.org/bookcrop.git (fast, but not encrypted)
git clone https://lumidify.org/bookcrop.git (encrypted, but very slow)
git clone git://4kcetb7mo7hj6grozzybxtotsub5bempzo4lirzc3437amof2c2impyd.onion/bookcrop.git (over tor)
Log | Files | Refs | 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()