2020
2121class 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):
595613class 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