Skip to content

Commit

Permalink
Continuous Handle cam_setting & cam_action (rotate done)
Browse files Browse the repository at this point in the history
js of cam_setting: Shutter Speed, Fnumber, ISO, WhiteBalance

js of cam_action: ActZoom In & Out, TouchAF, actHalfPressShutter, actTakePicture
(touchAF position after rotation changed handle by js)

py of cam_action: rotate done
  • Loading branch information
liuaddie committed Jan 8, 2023
1 parent 6e6d925 commit fdf12d8
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 62 deletions.
96 changes: 50 additions & 46 deletions controller.py
Expand Up @@ -22,35 +22,46 @@
f.get_frame_info = None
f.config['DEBUG'] = False

f.fps = 12
f.width = 600
f.height = 400
f.rotate = 0

@f.route("/")
def index():
return render_template("controller.html", id="C003")

def gen():
width = 640
height = 424
frame_rate = 6
while True:
if f.get_frame_handle is not None:
frame = f.get_frame_handle()
if f.get_frame_info is not None:
frame_img = bts_to_img(frame)
frame_img = cv2.resize(bts_to_img(frame), (f.width, f.height), interpolation = cv2.INTER_AREA)
frame_info = f.get_frame_info()
for x in range(len(frame_info)):
# print(frame_info[0])
category = frame_info[x]['category']
if category == 1:
status = frame_info[x]['status']
left = round(frame_info[x]['left'] * width / 10000)
top = round(frame_info[x]['top'] * height / 10000)
right = round(frame_info[x]['right'] * width / 10000)
bottom = round(frame_info[x]['bottom'] * height / 10000)
left = round(frame_info[x]['left'] * f.width / 10000)
top = round(frame_info[x]['top'] * f.height / 10000)
right = round(frame_info[x]['right'] * f.width / 10000)
bottom = round(frame_info[x]['bottom'] * f.height / 10000)
# print(left, top, right, bottom, category, status)
frame_img = cv2.rectangle(frame_img,(left,top),(right,bottom),(0,255,0),1)
frame = image_to_bts(frame_img)
match f.rotate:
case 1:
frame = image_to_bts(cv2.rotate(frame_img, cv2.ROTATE_90_CLOCKWISE))
case 2:
frame = image_to_bts(cv2.rotate(frame_img, cv2.ROTATE_180))
case 3:
frame = image_to_bts(cv2.rotate(frame_img, cv2.ROTATE_90_COUNTERCLOCKWISE))
case _:
frame = image_to_bts(frame_img)

yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
time.sleep(1/frame_rate)
time.sleep(1/f.fps)

@f.route('/video_feed')
def video_feed():
Expand All @@ -62,25 +73,30 @@ def cam_control():
action = request.json['action']
param = request.json['param']
print(cam_id, action, param)
if param != "":
params = param.split(",")
# Convert type of params
for p in range(len(params)):
print("Before Convert: ", p, params[p], type(params[p]))
if params[p].find("\'") < 0:
if params[p].strip().lower() == "true" or params[p].strip().lower() == "false" :
params[p] = bool(params[p])
# handle liveview rotation
if action == "rotate":
f.rotate = (f.rotate+int(param))%4
rs = str(f.rotate)
else:
if param != "":
params = param.split(",")
# Convert type of params
for p in range(len(params)):
print("Before Convert: ", p, params[p], type(params[p]))
if params[p].find("\'") < 0:
if params[p].strip().lower() == "true" or params[p].strip().lower() == "false" :
params[p] = bool(params[p])
else:
params[p] = int(params[p])
else:
params[p] = int(params[p])
else:
params[p] = eval(params[p].strip())
print("After Convert: ", p, params[p], type(params[p]))
params[p] = eval(params[p].strip())
print("After Convert: ", p, params[p], type(params[p]))

fn = getattr(s, action)
rs = fn(param=[*params])
else:
fn = getattr(s, action)
rs = fn()
fn = getattr(s, action)
rs = fn(param=[*params])
else:
fn = getattr(s, action)
rs = fn()

print(rs)
return rs
Expand Down Expand Up @@ -139,7 +155,7 @@ def liveview():
print("******** Start Controller ********")
print(d.get('id'), d.get('cam_ssid'), d.get('cam_pw'))

while not len(c.discover(3)):
while not len(c.discover(10)):
d.connect()
time.sleep(3)
else:
Expand All @@ -155,10 +171,12 @@ def liveview():
time.sleep(10)

api = s.getAvailableApiList()
# print("*"*23)
# print(api)
# print("*"*23)

print("*"*23)
print(api)
print("*"*23)
print("getAvailableLiveviewSize: ", s.getAvailableLiveviewSize())
time.sleep(3)

print("setLiveviewFrameInfo: ", s.setLiveviewFrameInfo(param=[{"frameInfo": True}]))
time.sleep(3)

Expand All @@ -167,17 +185,3 @@ def liveview():
f.get_frame_handle = handler
f.get_frame_info = info
f.run()


# print(s.getAvailablePostviewImageSize())
# postview = s.actTakePicture()['result'][0][0].replace("\\", "")
# print(postview)
# if postview.find('/'):
# filename = "Take_{}".format(postview.rsplit('/', 1)[1])
# print(filename)
# task_folder = "_temp"
# if not os.path.exists(task_folder):
# os.makedirs(task_folder)
# filepath = "{}/{}".format(task_folder, filename)
# download = requests.get(postview, allow_redirects=True)
# open(filepath, 'wb').write(download.content)
177 changes: 162 additions & 15 deletions templates/assets/js/btn_action.js
@@ -1,16 +1,163 @@
var dir = 1;
$('#cam_btn_rotate').click(function(){
cam_container = $(this).closest('.cam-container')
if(dir){
cam_container.find('.cam_feed_img').attr('src', 'cam_sample.jpg');
cam_container.removeClass('cam-horizontal');
cam_container.addClass('cam-vertical');
dir = 0;
} else{
cam_container.find('.cam_feed_img').attr('src', 'cam_sample_H.jpg');
cam_container.removeClass('cam-vertical');
cam_container.addClass('cam-horizontal');
dir = 1;
}
// Initizal Variables
var img_w = 600;
var img_h = 400;
var rot = 0;
// Hide the handle at the beginning
$('.drag-handle').hide();

// Function for Change Orientation
function changeOrientation() {
img_temp = img_w;
img_w = img_h;
img_h = img_temp;
console.log(img_w+'x'+img_h);
}

// Deactive cam_btn_focus if other button is clicked
function cancelFocus(cam_container) {
cam_container.find(".cam_btn_focus").removeClass("btn_on");
cam_container.find(".cam_feed_img").removeClass("img_on");
}

// Change Resolution
var res = "lg";
$('select[id="cam_set_res"]').change(function(){
all_cam_container = $('.cam-container');
res_old = "cam-"+res;
if ($(this).val() != res){
res = $(this).val();
res_new = "cam-"+res;
all_cam_container.removeClass(res_old);
all_cam_container.addClass(res_new);
console.log(res_new);
// sm = 200x300, md = 300x450, lg = 400x600
switch (res) {
case 'md':
img_w = 450;
img_h = 300;
break;
case 'sm':
img_w = 300;
img_h = 200;
break;
default:
img_w = 600;
img_h = 400;
};
};
});

// Disable dragging the images
$('img').on('dragstart', function(event) { event.preventDefault(); });

// Additional Function for Camera Action Buttons before and after
function cam_action_before(element){
// console.log('before:' + element.attr('cam_id'));
cam_container = element.closest('.cam-container')
cancelFocus(cam_container);

// Rotate the camera view
if (element.attr('action') == 'rotate'){
console.log('before:' + element.attr('action'));
img_elm = cam_container.find('.cam_feed_img');
rot = (rot+1) % 4;
if(rot % 2 == 1){
sample_img = 'cam_sample.jpg';
cam_container.removeClass('cam-horizontal');
cam_container.addClass('cam-vertical');
changeOrientation();
} else{
sample_img = 'cam_sample_H.jpg';
cam_container.removeClass('cam-vertical');
cam_container.addClass('cam-horizontal');
changeOrientation();
};
if (img_elm.attr("src").toLowerCase().indexOf(".jpg") >= 0){
img_elm.attr('src', sample_img);
};
};

})
// Lock
if (element.attr('action') == 'actHalfPressShutter'){
console.log('before:' + element.attr('action'));
element.toggleClass("btn_on");
cam_container.find('.cam_action').not('.dont_lock').prop('disabled', (i, v) => !v);
cam_container.find('.cam_btn_focus').prop('disabled', (i, v) => !v);
cam_container.find('.cam_setting').prop('disabled', (i, v) => !v);
};

};

// Function for Camera Action Buttons
// Share function with cam_action buttons and dropdowns
function cam_action(element){
cam_id = element.attr('cam_id');
action = element.attr('action');
if (element.hasClass('cam_setting')){
param = element.val();
} else {
param = element.attr('param') !== undefined ? element.attr('param') : '';
};
cam_action_before(element);
console.log(cam_id, action, param);
data = {'cam_id':cam_id, 'action':action, 'param':param};
$.ajax({
type : 'POST',
url : '/cam_control',
contentType: 'application/json;charset=UTF-8',
data : JSON.stringify(data)
});
};


$('.cam_action').click(function(){cam_action($(this))});
$('.cam_setting').change(function(){cam_action($(this))});

// Toogle Focus Button
$('.cam_btn_focus').click(function(){
$(this).toggleClass("btn_on");
cam_container = $(this).closest('.cam-container')
img_elm = cam_container.find('.cam_feed_img');
img_elm.toggleClass("img_on");
});

// POST touchAF
$(".cam_feed_img").click(function(event){
if ($(this).hasClass("img_on")){
var touchAF = {x: event.pageX - $(this).offset().left, y: event.pageY - $(this).offset().top};

touchAF.x = Math.round(touchAF.x/img_w*100);
touchAF.y = Math.round(touchAF.y/img_h*100);

touchAF.x = touchAF.x<=0 ? 1 : touchAF.x>100 ? 100 : touchAF.x;
touchAF.y = touchAF.y<=0 ? 1 : touchAF.y>100 ? 100 : touchAF.y;
console.log(touchAF);

switch(rot){
case 1:
temp = touchAF.y;
touchAF.y = 100-touchAF.x;
touchAF.x = temp;
break
case 2:
touchAF.y = 100-touchAF.y;
touchAF.x = 100-touchAF.x;
break
case 3:
temp = touchAF.x;
touchAF.y = temp;
touchAF.x = 100-touchAF.y;
break
}


data = {'cam_id': '', 'action': 'setTouchAFPosition', 'param':touchAF.x+","+touchAF.y};
$.ajax({
type : 'POST',
url : '/cam_control',
contentType: 'application/json;charset=UTF-8',
data : JSON.stringify(data),
context: this
}).always(cancelFocus($(this).closest('.cam-container')));
};
});
2 changes: 1 addition & 1 deletion templates/controller.html
Expand Up @@ -149,7 +149,7 @@
</path>
</svg>
</button>
<button action="rotate" cam_id="Z999" class="btn btn-sm cam_action" param="clockwise" title="Rotate" type="button">
<button action="rotate" cam_id="Z999" class="btn btn-sm cam_action" param="1" title="Rotate" type="button">
<svg class="bi bi-arrow-clockwise" fill="currentColor" height="1em" viewbox="0 0 16 16" width="1em" xmlns="http://www.w3.org/2000/svg">
<path d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z" fill-rule="evenodd">
</path>
Expand Down

0 comments on commit fdf12d8

Please sign in to comment.