-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathview_live.py
More file actions
113 lines (103 loc) · 4.61 KB
/
Copy pathview_live.py
File metadata and controls
113 lines (103 loc) · 4.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import cv2
from lsb_filter import apply_filter
from file_io import load_image_raw, load_video_raw
_F = cv2.FONT_HERSHEY_PLAIN
UI_H = 65
_st = {}
class _Btn:
def __init__(self, l, x, y, w, h, tag, tp):
self.label=l; self.x=x; self.y=y; self.w=w; self.h=h; self.tag=tag; self.type=tp
def hit(self, rx, ry):
return self.x<=rx<=self.x+self.w and self.y<=ry<=self.y+self.h
def _btns(ww):
y, h = 18, 30
def b(l, x, w, tag, tp): return _Btn(l, x, y, w, h, tag, tp)
return [
b("1-BIT", 15, 70, "1BIT", "mode"),
b("2-BIT", 95, 70, "2BIT", "mode"),
b("3-BIT", 175, 70, "3BIT", "mode"),
b("● REC", 265, 80, "REC", "action"),
b("SCRUB", 355, 80, "SCRUB", "action"),
b("Load Img", 445, 90, "LOAD_IMG", "action"),
b("Load Vid", 545, 90, "LOAD_VID", "action"),
b("R", ww-165, 40, "R", "channel"),
b("G", ww-115, 40, "G", "channel"),
b("B", ww-65, 40, "B", "channel"),
]
def _draw_ui(canvas, ww, wh, buttons, mode, channels, recording, buf_count):
base = wh - UI_H
ov = canvas.copy()
cv2.rectangle(ov, (0, base), (ww, wh), (18, 18, 22), -1)
cv2.addWeighted(ov, 0.88, canvas, 0.12, 0, canvas)
for btn in buttons:
lbl = btn.label; color = (55, 55, 62); tc = (180, 180, 188)
if btn.type == "mode":
if mode == btn.tag: color = (0, 140, 20); tc = (230, 255, 230)
elif btn.type == "channel":
if channels.get(btn.tag):
color = {"B": (155,18,18), "G": (18,155,18), "R": (18,18,155)}.get(btn.tag, (55,55,62))
tc = (255, 255, 255)
else:
tc = (52, 52, 58)
elif btn.type == "action":
if btn.tag == "REC":
color = (18,18,155) if recording else (44,44,50)
tc = (255,55,55) if recording else (155,155,155)
lbl = "■ REC" if recording else "● REC"
elif btn.tag == "SCRUB":
color = (58,48,8) if buf_count > 0 else (28,28,28)
tc = (238,188,55) if buf_count > 0 else (58,58,58)
elif btn.tag in ("LOAD_IMG", "LOAD_VID"):
color = (28, 68, 28); tc = (168, 228, 168)
bx = btn.x; by = base + btn.y
cv2.rectangle(canvas, (bx, by), (bx+btn.w, by+btn.h), color, -1)
cv2.rectangle(canvas, (bx, by), (bx+btn.w, by+btn.h), (125,125,135), 1)
ts = cv2.getTextSize(lbl, _F, 0.9, 1)[0]
cv2.putText(canvas, lbl, (bx+(btn.w-ts[0])//2, by+(btn.h+ts[1])//2), _F, 0.9, tc, 1)
if buf_count > 0:
cv2.putText(canvas, f"{buf_count}f", (648, base+38), _F, 0.9, (115,115,128), 1)
def on_enter(buf, cap):
_st.setdefault("mode", "1BIT")
_st.setdefault("channels", {"R": True, "G": True, "B": True})
_st["buf"] = buf
_st["cap"] = cap
def render(canvas, ww, wh, events):
buf = _st["buf"]; cap = _st["cap"]
mx, my = events["cursor"]
frame = cap.grab(mx - ww//2, my - wh//2, ww, wh)
if frame is not None:
buf.push(frame)
filtered = apply_filter(frame, _st["mode"], _st["channels"])
fh, fw = filtered.shape[:2]
canvas[:min(fh,wh), :min(fw,ww)] = filtered[:wh, :ww]
buttons = _btns(ww)
wr = events["win_rect"]
inside = bool(wr and wr[2] > 0 and
wr[0] <= mx <= wr[0]+wr[2] and wr[1] <= my <= wr[1]+wr[3])
for ev, x, y, flags in events["mouse"]:
if ev == cv2.EVENT_LBUTTONDOWN and y >= wh - UI_H:
rel_y = y - (wh - UI_H)
for b in buttons:
if b.hit(x, rel_y):
if b.type == "mode":
_st["mode"] = b.tag
elif b.type == "channel":
_st["channels"][b.tag] = not _st["channels"][b.tag]
elif b.type == "action":
if b.tag == "REC":
buf.toggle()
elif b.tag == "SCRUB" and buf.count() > 0:
return {"to": "scrub", "frames": buf.get_frames()}
elif b.tag == "LOAD_IMG":
new_f, _ = load_image_raw()
if new_f: buf.replace(buf.get_frames() + new_f)
elif b.tag == "LOAD_VID":
new_f, _ = load_video_raw()
if new_f: buf.replace(buf.get_frames() + new_f)
if inside:
_draw_ui(canvas, ww, wh, buttons, _st["mode"], _st["channels"],
buf.recording, buf.count())
k = events["key"]
if k in (ord('q'), ord('Q')):
return {"quit": True}
return None