Skip to content

Commit bfbf52b

Browse files
Zoomed on center and more resolutions
1 parent 920edd8 commit bfbf52b

File tree

1 file changed

+153
-54
lines changed
  • internal_filesystem/apps/com.micropythonos.camera/assets

1 file changed

+153
-54
lines changed

internal_filesystem/apps/com.micropythonos.camera/assets/camera_app.py

Lines changed: 153 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020

2121
class CameraApp(Activity):
2222

23-
button_width = 40
24-
button_height = 40
23+
button_width = 60
24+
button_height = 45
2525
width = 320
2626
height = 240
2727

@@ -82,7 +82,7 @@ def onCreate(self):
8282
# Settings button
8383
settings_button = lv.button(self.main_screen)
8484
settings_button.set_size(self.button_width, self.button_height)
85-
settings_button.align(lv.ALIGN.TOP_RIGHT, 0, self.button_height + 10)
85+
settings_button.align(lv.ALIGN.TOP_RIGHT, 0, self.button_height + 5)
8686
settings_label = lv.label(settings_button)
8787
settings_label.set_text(lv.SYMBOL.SETTINGS)
8888
settings_label.center()
@@ -98,8 +98,7 @@ def onCreate(self):
9898
snap_label.center()
9999
self.zoom_button = lv.button(self.main_screen)
100100
self.zoom_button.set_size(self.button_width, self.button_height)
101-
self.zoom_button.align(lv.ALIGN.RIGHT_MID, 0, self.button_height + 10)
102-
#self.zoom_button.add_flag(lv.obj.FLAG.HIDDEN)
101+
self.zoom_button.align(lv.ALIGN.RIGHT_MID, 0, self.button_height + 5)
103102
self.zoom_button.add_event_cb(self.zoom_button_click,lv.EVENT.CLICKED,None)
104103
zoom_label = lv.label(self.zoom_button)
105104
zoom_label.set_text("Z")
@@ -135,7 +134,7 @@ def onResume(self, screen):
135134
self.cam = init_internal_cam(self.width, self.height)
136135
if self.cam:
137136
self.image.set_rotation(900) # internal camera is rotated 90 degrees
138-
# Apply saved camera settings
137+
# Apply saved camera settings, only for internal camera for now:
139138
apply_camera_settings(self.cam, self.use_webcam)
140139
else:
141140
print("camera app: no internal camera found, trying webcam on /dev/video0")
@@ -294,9 +293,26 @@ def qr_button_click(self, e):
294293

295294
def zoom_button_click(self, e):
296295
print("zooming...")
296+
if self.use_webcam:
297+
print("zoom_button_click is not supported for webcam")
298+
return
297299
if self.cam:
298-
# This might work as it's what works in the C code:
299-
self.cam.set_res_raw(startX=0,startY=0,endX=2623,endY=1951,offsetX=992,offsetY=736,totalX=2844,totalY=2844,outputX=640,outputY=480,scale=False,binning=False)
300+
prefs = SharedPreferences("com.micropythonos.camera")
301+
startX = prefs.get_int("startX", CameraSettingsActivity.startX_default)
302+
startY = prefs.get_int("startX", CameraSettingsActivity.startY_default)
303+
endX = prefs.get_int("startX", CameraSettingsActivity.endX_default)
304+
endY = prefs.get_int("startX", CameraSettingsActivity.endY_default)
305+
offsetX = prefs.get_int("startX", CameraSettingsActivity.offsetX_default)
306+
offsetY = prefs.get_int("startX", CameraSettingsActivity.offsetY_default)
307+
totalX = prefs.get_int("startX", CameraSettingsActivity.totalX_default)
308+
totalY = prefs.get_int("startX", CameraSettingsActivity.totalY_default)
309+
outputX = prefs.get_int("startX", CameraSettingsActivity.outputX_default)
310+
outputY = prefs.get_int("startX", CameraSettingsActivity.outputY_default)
311+
scale = prefs.get_bool("scale", CameraSettingsActivity.scale_default)
312+
binning = prefs.get_bool("binning", CameraSettingsActivity.binning_default)
313+
# This works as it's what works in the C code:
314+
result = self.cam.set_res_raw(startX,startY,endX,endY,offsetX,offsetY,totalX,totalY,outputX,outputY,scale,binning)
315+
print(f"self.cam.set_res_raw returned {result}")
300316

301317
def open_settings(self):
302318
self.image_dsc.data = None
@@ -401,15 +417,17 @@ def init_internal_cam(width, height):
401417
resolution_map = {
402418
(96, 96): FrameSize.R96X96,
403419
(160, 120): FrameSize.QQVGA,
404-
#(128, 128): FrameSize.R128X128, it's actually FrameSize.R128x128 but let's ignore it to be safe
420+
(128, 128): FrameSize.R128X128,
405421
(176, 144): FrameSize.QCIF,
406422
(240, 176): FrameSize.HQVGA,
407423
(240, 240): FrameSize.R240X240,
408424
(320, 240): FrameSize.QVGA,
409425
(320, 320): FrameSize.R320X320,
410426
(400, 296): FrameSize.CIF,
411427
(480, 320): FrameSize.HVGA,
428+
(480, 480): FrameSize.R480X480,
412429
(640, 480): FrameSize.VGA,
430+
(640, 640): FrameSize.R640X640,
413431
(800, 600): FrameSize.SVGA,
414432
(1024, 768): FrameSize.XGA,
415433
(1280, 720): FrameSize.HD,
@@ -595,6 +613,21 @@ def apply_camera_settings(cam, use_webcam):
595613
class CameraSettingsActivity(Activity):
596614
"""Settings activity for comprehensive camera configuration."""
597615

616+
# Original: { 2560, 1920, 0, 0, 2623, 1951, 32, 16, 2844, 1968 }
617+
# Worked for digital zoom in C: { 2560, 1920, 0, 0, 2623, 1951, 992, 736, 2844, 1968 }
618+
startX_default=0
619+
startY_default=0
620+
endX_default=2623
621+
endY_default=1951
622+
offsetX_default=32
623+
offsetY_default=16
624+
totalX_default=2844
625+
totalY_default=1968
626+
outputX_default=640
627+
outputY_default=480
628+
scale_default=False
629+
binning_default=False
630+
598631
# Resolution options for desktop/webcam
599632
WEBCAM_RESOLUTIONS = [
600633
("160x120", "160x120"),
@@ -618,10 +651,12 @@ class CameraSettingsActivity(Activity):
618651
("320x320", "320x320"),
619652
("400x296", "400x296"),
620653
("480x320", "480x320"),
654+
("480x480", "480x480"),
621655
("640x480", "640x480"),
656+
("640x640", "640x640"),
622657
("800x600", "800x600"),
623658
("1024x768", "1024x768"),
624-
("1280x720", "1280x720"),
659+
("1280x720", "1280x720"), # binned 2x2
625660
("1280x1024", "1280x1024"),
626661
("1600x1200", "1600x1200"),
627662
("1920x1080", "1920x1080"),
@@ -659,8 +694,8 @@ def onCreate(self):
659694

660695
# Create tabview
661696
tabview = lv.tabview(screen)
662-
tabview.set_tab_bar_size(mpos.ui.pct_of_display_height(10))
663-
tabview.set_size(lv.pct(100), mpos.ui.pct_of_display_height(80))
697+
tabview.set_tab_bar_size(mpos.ui.pct_of_display_height(15))
698+
#tabview.set_size(lv.pct(100), mpos.ui.pct_of_display_height(80))
664699

665700
# Create Basic tab (always)
666701
basic_tab = tabview.add_tab("Basic")
@@ -677,38 +712,6 @@ def onCreate(self):
677712
raw_tab = tabview.add_tab("Raw")
678713
self.create_raw_tab(raw_tab, prefs)
679714

680-
# Save/Cancel buttons at bottom
681-
self.button_cont = lv.obj(screen)
682-
self.button_cont.set_size(lv.pct(100), mpos.ui.pct_of_display_height(20))
683-
self.button_cont.remove_flag(lv.obj.FLAG.SCROLLABLE)
684-
self.button_cont.align(lv.ALIGN.BOTTOM_MID, 0, 0)
685-
self.button_cont.set_style_border_width(0, 0)
686-
self.button_cont.set_style_bg_opa(0, 0)
687-
688-
save_button = lv.button(self.button_cont)
689-
save_button.set_size(mpos.ui.pct_of_display_width(25), lv.SIZE_CONTENT)
690-
save_button.align(lv.ALIGN.BOTTOM_LEFT, 0, 0)
691-
save_button.add_event_cb(lambda e: self.save_and_close(), lv.EVENT.CLICKED, None)
692-
save_label = lv.label(save_button)
693-
save_label.set_text("Save")
694-
save_label.center()
695-
696-
cancel_button = lv.button(self.button_cont)
697-
cancel_button.set_size(mpos.ui.pct_of_display_width(25), lv.SIZE_CONTENT)
698-
cancel_button.align(lv.ALIGN.BOTTOM_MID, 0, 0)
699-
cancel_button.add_event_cb(lambda e: self.finish(), lv.EVENT.CLICKED, None)
700-
cancel_label = lv.label(cancel_button)
701-
cancel_label.set_text("Cancel")
702-
cancel_label.center()
703-
704-
erase_button = lv.button(self.button_cont)
705-
erase_button.set_size(mpos.ui.pct_of_display_width(25), lv.SIZE_CONTENT)
706-
erase_button.align(lv.ALIGN.BOTTOM_RIGHT, 0, 0)
707-
erase_button.add_event_cb(lambda e: self.erase_and_close(), lv.EVENT.CLICKED, None)
708-
erase_label = lv.label(erase_button)
709-
erase_label.set_text("Erase")
710-
erase_label.center()
711-
712715
self.setContentView(screen)
713716

714717
def create_slider(self, parent, label_text, min_val, max_val, default_val, pref_key):
@@ -779,17 +782,18 @@ def create_dropdown(self, parent, label_text, options, default_idx, pref_key):
779782

780783
def create_textarea(self, parent, label_text, min_val, max_val, default_val, pref_key):
781784
cont = lv.obj(parent)
782-
cont.set_size(lv.pct(100), 60)
785+
cont.set_size(lv.pct(100), lv.SIZE_CONTENT)
783786
cont.set_style_pad_all(3, 0)
784787

785788
label = lv.label(cont)
786-
label.set_text(f"{label_text}: {default_val}")
789+
label.set_text(f"{label_text}:")
787790
label.align(lv.ALIGN.TOP_LEFT, 0, 0)
788791

789-
textarea = lv.textarea(parent)
790-
textarea.set_width(lv.pct(90))
792+
textarea = lv.textarea(cont)
793+
textarea.set_width(lv.pct(50))
791794
textarea.set_one_line(True) # might not be good for all settings but it's good for most
792795
textarea.set_text(str(default_val))
796+
textarea.align(lv.ALIGN.TOP_RIGHT, 0, 0)
793797

794798
# Initialize keyboard (hidden initially)
795799
keyboard = MposKeyboard(parent)
@@ -803,7 +807,7 @@ def create_textarea(self, parent, label_text, min_val, max_val, default_val, pre
803807
return textarea, cont
804808

805809
def show_keyboard(self, kbd):
806-
self.button_cont.add_flag(lv.obj.FLAG.HIDDEN)
810+
#self.button_cont.add_flag(lv.obj.FLAG.HIDDEN)
807811
mpos.ui.anim.smooth_show(kbd)
808812
focusgroup = lv.group_get_default()
809813
if focusgroup:
@@ -815,7 +819,41 @@ def show_keyboard(self, kbd):
815819

816820
def hide_keyboard(self, kbd):
817821
mpos.ui.anim.smooth_hide(kbd)
818-
self.button_cont.remove_flag(lv.obj.FLAG.HIDDEN)
822+
#self.button_cont.remove_flag(lv.obj.FLAG.HIDDEN)
823+
824+
def add_buttons(self, parent):
825+
# Save/Cancel buttons at bottom
826+
button_cont = lv.obj(parent)
827+
button_cont.set_size(lv.pct(100), mpos.ui.pct_of_display_height(20))
828+
button_cont.remove_flag(lv.obj.FLAG.SCROLLABLE)
829+
button_cont.align(lv.ALIGN.BOTTOM_MID, 0, 0)
830+
button_cont.set_style_border_width(0, 0)
831+
button_cont.set_style_bg_opa(0, 0)
832+
833+
save_button = lv.button(button_cont)
834+
save_button.set_size(mpos.ui.pct_of_display_width(25), lv.SIZE_CONTENT)
835+
save_button.align(lv.ALIGN.BOTTOM_LEFT, 0, 0)
836+
save_button.add_event_cb(lambda e: self.save_and_close(), lv.EVENT.CLICKED, None)
837+
save_label = lv.label(save_button)
838+
save_label.set_text("Save")
839+
save_label.center()
840+
841+
cancel_button = lv.button(button_cont)
842+
cancel_button.set_size(mpos.ui.pct_of_display_width(25), lv.SIZE_CONTENT)
843+
cancel_button.align(lv.ALIGN.BOTTOM_MID, 0, 0)
844+
cancel_button.add_event_cb(lambda e: self.finish(), lv.EVENT.CLICKED, None)
845+
cancel_label = lv.label(cancel_button)
846+
cancel_label.set_text("Cancel")
847+
cancel_label.center()
848+
849+
erase_button = lv.button(button_cont)
850+
erase_button.set_size(mpos.ui.pct_of_display_width(25), lv.SIZE_CONTENT)
851+
erase_button.align(lv.ALIGN.BOTTOM_RIGHT, 0, 0)
852+
erase_button.add_event_cb(lambda e: self.erase_and_close(), lv.EVENT.CLICKED, None)
853+
erase_label = lv.label(erase_button)
854+
erase_label.set_text("Erase")
855+
erase_label.center()
856+
819857

820858
def create_basic_tab(self, tab, prefs):
821859
"""Create Basic settings tab."""
@@ -869,6 +907,8 @@ def create_basic_tab(self, tab, prefs):
869907
special_effect, "special_effect")
870908
self.ui_controls["special_effect"] = dropdown
871909

910+
self.add_buttons(tab)
911+
872912
def create_advanced_tab(self, tab, prefs):
873913
"""Create Advanced settings tab."""
874914
#tab.set_scrollbar_mode(lv.SCROLLBAR_MODE.AUTO)
@@ -979,6 +1019,8 @@ def whitebal_changed(e):
9791019
checkbox, cont = self.create_checkbox(tab, "AWB Gain", awb_gain, "awb_gain")
9801020
self.ui_controls["awb_gain"] = checkbox
9811021

1022+
self.add_buttons(tab)
1023+
9821024
def create_expert_tab(self, tab, prefs):
9831025
"""Create Expert settings tab."""
9841026
#tab.set_scrollbar_mode(lv.SCROLLBAR_MODE.AUTO)
@@ -1051,11 +1093,64 @@ def create_expert_tab(self, tab, prefs):
10511093
checkbox, cont = self.create_checkbox(tab, "Lens Correction", lenc, "lenc")
10521094
self.ui_controls["lenc"] = checkbox
10531095

1096+
self.add_buttons(tab)
1097+
10541098
def create_raw_tab(self, tab, prefs):
1055-
startX = prefs.get_int("startX", 0)
1099+
tab.set_flex_flow(lv.FLEX_FLOW.COLUMN)
1100+
tab.set_style_pad_all(0, 0)
1101+
1102+
# This would be nice but does not provide adequate resolution:
10561103
#startX, label, cont = self.create_slider(tab, "startX", 0, 2844, startX, "startX")
1104+
1105+
startX = prefs.get_int("startX", self.startX_default)
10571106
textarea, cont = self.create_textarea(tab, "startX", 0, 2844, startX, "startX")
1058-
self.ui_controls["startX"] = startX
1107+
self.ui_controls["startX"] = textarea
1108+
1109+
startY = prefs.get_int("startY", self.startY_default)
1110+
textarea, cont = self.create_textarea(tab, "startY", 0, 2844, startY, "startY")
1111+
self.ui_controls["startY"] = textarea
1112+
1113+
endX = prefs.get_int("endX", self.endX_default)
1114+
textarea, cont = self.create_textarea(tab, "endX", 0, 2844, endX, "endX")
1115+
self.ui_controls["endX"] = textarea
1116+
1117+
endY = prefs.get_int("endY", self.endY_default)
1118+
textarea, cont = self.create_textarea(tab, "endY", 0, 2844, endY, "endY")
1119+
self.ui_controls["endY"] = textarea
1120+
1121+
offsetX = prefs.get_int("offsetX", self.offsetX_default)
1122+
textarea, cont = self.create_textarea(tab, "offsetX", 0, 2844, offsetX, "offsetX")
1123+
self.ui_controls["offsetX"] = textarea
1124+
1125+
offsetY = prefs.get_int("offsetY", self.offsetY_default)
1126+
textarea, cont = self.create_textarea(tab, "offsetY", 0, 2844, offsetY, "offsetY")
1127+
self.ui_controls["offsetY"] = textarea
1128+
1129+
totalX = prefs.get_int("totalX", self.totalX_default)
1130+
textarea, cont = self.create_textarea(tab, "totalX", 0, 2844, totalX, "totalX")
1131+
self.ui_controls["totalX"] = textarea
1132+
1133+
totalY = prefs.get_int("totalY", self.totalY_default)
1134+
textarea, cont = self.create_textarea(tab, "totalY", 0, 2844, totalY, "totalY")
1135+
self.ui_controls["totalY"] = textarea
1136+
1137+
outputX = prefs.get_int("outputX", self.outputX_default)
1138+
textarea, cont = self.create_textarea(tab, "outputX", 0, 2844, outputX, "outputX")
1139+
self.ui_controls["outputX"] = textarea
1140+
1141+
outputY = prefs.get_int("outputY", self.outputY_default)
1142+
textarea, cont = self.create_textarea(tab, "outputY", 0, 2844, outputY, "outputY")
1143+
self.ui_controls["outputY"] = textarea
1144+
1145+
scale = prefs.get_bool("scale", self.scale_default)
1146+
checkbox, cont = self.create_checkbox(tab, "Scale?", scale, "scale")
1147+
self.ui_controls["scale"] = checkbox
1148+
1149+
binning = prefs.get_bool("binning", self.binning_default)
1150+
checkbox, cont = self.create_checkbox(tab, "Binning?", binning, "binning")
1151+
self.ui_controls["binning"] = checkbox
1152+
1153+
self.add_buttons(tab)
10591154

10601155
def erase_and_close(self):
10611156
SharedPreferences("com.micropythonos.camera").edit().remove_all().commit()
@@ -1069,6 +1164,7 @@ def save_and_close(self):
10691164

10701165
# Save all UI control values
10711166
for pref_key, control in self.ui_controls.items():
1167+
print(f"saving {pref_key} with {control}")
10721168
control_id = id(control)
10731169
metadata = self.control_metadata.get(control_id, {})
10741170

@@ -1079,8 +1175,11 @@ def save_and_close(self):
10791175
is_checked = control.get_state() & lv.STATE.CHECKED
10801176
editor.put_bool(pref_key, bool(is_checked))
10811177
elif isinstance(control, lv.textarea):
1082-
value = int(control.get_value())
1083-
editor.put_int(pref_key, value)
1178+
try:
1179+
value = int(control.get_text())
1180+
editor.put_int(pref_key, value)
1181+
except Exception as e:
1182+
print(f"Error while trying to save {pref_key}: {e}")
10841183
elif isinstance(control, lv.dropdown):
10851184
selected_idx = control.get_selected()
10861185
option_values = metadata.get("option_values", [])

0 commit comments

Comments
 (0)