Skip to content

Commit d4239b6

Browse files
Camera app: improve settings handling
1 parent e3157a7 commit d4239b6

File tree

2 files changed

+58
-63
lines changed

2 files changed

+58
-63
lines changed

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

Lines changed: 50 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import mpos.time
99
from mpos.apps import Activity
10-
from mpos.config import SharedPreferences
1110
from mpos.content.intent import Intent
1211

1312
from camera_settings import CameraSettingsActivity
@@ -16,7 +15,7 @@ class CameraApp(Activity):
1615

1716
DEFAULT_WIDTH = 320 # 240 would be better but webcam doesn't support this (yet)
1817
DEFAULT_HEIGHT = 240
19-
APPNAME = "com.micropythonos.camera"
18+
PACKAGE = "com.micropythonos.camera"
2019
#DEFAULT_CONFIG = "config.json"
2120
#QRCODE_CONFIG = "config_qrmode.json"
2221

@@ -50,7 +49,10 @@ class CameraApp(Activity):
5049
status_label_cont = None
5150

5251
def onCreate(self):
52+
from mpos.config import SharedPreferences
53+
self.prefs = SharedPreferences(self.PACKAGE)
5354
self.scanqr_mode = self.getIntent().extras.get("scanqr_mode")
55+
5456
self.main_screen = lv.obj()
5557
self.main_screen.set_style_pad_all(1, 0)
5658
self.main_screen.set_style_border_width(0, 0)
@@ -115,7 +117,8 @@ def onCreate(self):
115117
self.setContentView(self.main_screen)
116118

117119
def onResume(self, screen):
118-
self.load_resolution_preference() # needs to be done BEFORE the camera is initialized
120+
self.parse_camera_init_preferences()
121+
# Init camera:
119122
self.cam = init_internal_cam(self.width, self.height)
120123
if self.cam:
121124
self.image.set_rotation(900) # internal camera is rotated 90 degrees
@@ -130,6 +133,7 @@ def onResume(self, screen):
130133
self.use_webcam = True
131134
except Exception as e:
132135
print(f"camera app: webcam exception: {e}")
136+
# Start refreshing:
133137
if self.cam:
134138
print("Camera app initialized, continuing...")
135139
self.update_preview_image()
@@ -169,11 +173,9 @@ def onPause(self, screen):
169173
print(f"Warning: powering off camera got exception: {e}")
170174
print("camera app cleanup done.")
171175

172-
def load_resolution_preference(self):
173-
"""Load resolution preference from SharedPreferences and update width/height."""
174-
prefs = SharedPreferences(CameraApp.APPNAME)
175-
resolution_str = prefs.get_string("resolution", f"{self.DEFAULT_WIDTH}x{self.DEFAULT_HEIGHT}")
176-
self.colormode = prefs.get_bool("colormode", False)
176+
def parse_camera_init_preferences(self):
177+
resolution_str = self.prefs.get_string("resolution", f"{self.DEFAULT_WIDTH}x{self.DEFAULT_HEIGHT}")
178+
self.colormode = self.prefs.get_bool("colormode", False)
177179
try:
178180
width_str, height_str = resolution_str.split('x')
179181
self.width = int(width_str)
@@ -287,26 +289,25 @@ def zoom_button_click(self, e):
287289
print("zoom_button_click is not supported for webcam")
288290
return
289291
if self.cam:
290-
prefs = SharedPreferences(CameraApp.APPNAME)
291-
startX = prefs.get_int("startX", CameraSettingsActivity.startX_default)
292-
startY = prefs.get_int("startX", CameraSettingsActivity.startY_default)
293-
endX = prefs.get_int("startX", CameraSettingsActivity.endX_default)
294-
endY = prefs.get_int("startX", CameraSettingsActivity.endY_default)
295-
offsetX = prefs.get_int("startX", CameraSettingsActivity.offsetX_default)
296-
offsetY = prefs.get_int("startX", CameraSettingsActivity.offsetY_default)
297-
totalX = prefs.get_int("startX", CameraSettingsActivity.totalX_default)
298-
totalY = prefs.get_int("startX", CameraSettingsActivity.totalY_default)
299-
outputX = prefs.get_int("startX", CameraSettingsActivity.outputX_default)
300-
outputY = prefs.get_int("startX", CameraSettingsActivity.outputY_default)
301-
scale = prefs.get_bool("scale", CameraSettingsActivity.scale_default)
302-
binning = prefs.get_bool("binning", CameraSettingsActivity.binning_default)
292+
startX = self.prefs.get_int("startX", CameraSettingsActivity.startX_default)
293+
startY = self.prefs.get_int("startX", CameraSettingsActivity.startY_default)
294+
endX = self.prefs.get_int("startX", CameraSettingsActivity.endX_default)
295+
endY = self.prefs.get_int("startX", CameraSettingsActivity.endY_default)
296+
offsetX = self.prefs.get_int("startX", CameraSettingsActivity.offsetX_default)
297+
offsetY = self.prefs.get_int("startX", CameraSettingsActivity.offsetY_default)
298+
totalX = self.prefs.get_int("startX", CameraSettingsActivity.totalX_default)
299+
totalY = self.prefs.get_int("startX", CameraSettingsActivity.totalY_default)
300+
outputX = self.prefs.get_int("startX", CameraSettingsActivity.outputX_default)
301+
outputY = self.prefs.get_int("startX", CameraSettingsActivity.outputY_default)
302+
scale = self.prefs.get_bool("scale", CameraSettingsActivity.scale_default)
303+
binning = self.prefs.get_bool("binning", CameraSettingsActivity.binning_default)
303304
result = self.cam.set_res_raw(startX,startY,endX,endY,offsetX,offsetY,totalX,totalY,outputX,outputY,scale,binning)
304305
print(f"self.cam.set_res_raw returned {result}")
305306

306307
def open_settings(self):
307308
self.image_dsc.data = None
308309
self.current_cam_buffer = None
309-
intent = Intent(activity_class=CameraSettingsActivity, extras={"use_webcam": self.use_webcam, "scanqr_mode": self.scanqr_mode})
310+
intent = Intent(activity_class=CameraSettingsActivity, extras={"prefs": self.prefs, "use_webcam": self.use_webcam, "scanqr_mode": self.scanqr_mode})
310311
self.startActivity(intent)
311312

312313
def try_capture(self, event):
@@ -315,9 +316,7 @@ def try_capture(self, event):
315316
if self.use_webcam:
316317
self.current_cam_buffer = webcam.capture_frame(self.cam, "rgb565" if self.colormode else "grayscale")
317318
elif self.cam.frame_available():
318-
#self.cam.free_buffer()
319319
self.current_cam_buffer = self.cam.capture()
320-
#self.cam.free_buffer()
321320

322321
if self.current_cam_buffer and len(self.current_cam_buffer):
323322
# Defensive check: verify buffer size matches expected dimensions
@@ -329,7 +328,7 @@ def try_capture(self, event):
329328
#self.image.invalidate() # does not work so do this:
330329
self.image.set_src(self.image_dsc)
331330
if not self.use_webcam:
332-
self.cam.free_buffer() # Free the old buffer
331+
self.cam.free_buffer() # Free the old buffer, otherwise the camera doesn't provide a new one
333332
try:
334333
if self.keepliveqrdecoding:
335334
self.qrdecode_one()
@@ -438,7 +437,7 @@ def remove_bom(buffer):
438437

439438

440439
def apply_camera_settings(cam, use_webcam):
441-
"""Apply all saved camera settings from SharedPreferences to ESP32 camera.
440+
"""Apply all saved camera settings to the camera.
442441
443442
Only applies settings when use_webcam is False (ESP32 camera).
444443
Settings are applied in dependency order (master switches before dependent values).
@@ -451,101 +450,99 @@ def apply_camera_settings(cam, use_webcam):
451450
print("apply_camera_settings: Skipping (no camera or webcam mode)")
452451
return
453452

454-
prefs = SharedPreferences(CameraApp.APPNAME)
455-
456453
try:
457454
# Basic image adjustments
458-
brightness = prefs.get_int("brightness", 0)
455+
brightness = self.prefs.get_int("brightness", 0)
459456
cam.set_brightness(brightness)
460457

461-
contrast = prefs.get_int("contrast", 0)
458+
contrast = self.prefs.get_int("contrast", 0)
462459
cam.set_contrast(contrast)
463460

464-
saturation = prefs.get_int("saturation", 0)
461+
saturation = self.prefs.get_int("saturation", 0)
465462
cam.set_saturation(saturation)
466463

467464
# Orientation
468-
hmirror = prefs.get_bool("hmirror", False)
465+
hmirror = self.prefs.get_bool("hmirror", False)
469466
cam.set_hmirror(hmirror)
470467

471-
vflip = prefs.get_bool("vflip", True)
468+
vflip = self.prefs.get_bool("vflip", True)
472469
cam.set_vflip(vflip)
473470

474471
# Special effect
475-
special_effect = prefs.get_int("special_effect", 0)
472+
special_effect = self.prefs.get_int("special_effect", 0)
476473
cam.set_special_effect(special_effect)
477474

478475
# Exposure control (apply master switch first, then manual value)
479-
exposure_ctrl = prefs.get_bool("exposure_ctrl", True)
476+
exposure_ctrl = self.prefs.get_bool("exposure_ctrl", True)
480477
cam.set_exposure_ctrl(exposure_ctrl)
481478

482479
if not exposure_ctrl:
483-
aec_value = prefs.get_int("aec_value", 300)
480+
aec_value = self.prefs.get_int("aec_value", 300)
484481
cam.set_aec_value(aec_value)
485482

486-
ae_level = prefs.get_int("ae_level", 0)
483+
ae_level = self.prefs.get_int("ae_level", 0)
487484
cam.set_ae_level(ae_level)
488485

489-
aec2 = prefs.get_bool("aec2", False)
486+
aec2 = self.prefs.get_bool("aec2", False)
490487
cam.set_aec2(aec2)
491488

492489
# Gain control (apply master switch first, then manual value)
493-
gain_ctrl = prefs.get_bool("gain_ctrl", True)
490+
gain_ctrl = self.prefs.get_bool("gain_ctrl", True)
494491
cam.set_gain_ctrl(gain_ctrl)
495492

496493
if not gain_ctrl:
497-
agc_gain = prefs.get_int("agc_gain", 0)
494+
agc_gain = self.prefs.get_int("agc_gain", 0)
498495
cam.set_agc_gain(agc_gain)
499496

500-
gainceiling = prefs.get_int("gainceiling", 0)
497+
gainceiling = self.prefs.get_int("gainceiling", 0)
501498
cam.set_gainceiling(gainceiling)
502499

503500
# White balance (apply master switch first, then mode)
504-
whitebal = prefs.get_bool("whitebal", True)
501+
whitebal = self.prefs.get_bool("whitebal", True)
505502
cam.set_whitebal(whitebal)
506503

507504
if not whitebal:
508-
wb_mode = prefs.get_int("wb_mode", 0)
505+
wb_mode = self.prefs.get_int("wb_mode", 0)
509506
cam.set_wb_mode(wb_mode)
510507

511-
awb_gain = prefs.get_bool("awb_gain", True)
508+
awb_gain = self.prefs.get_bool("awb_gain", True)
512509
cam.set_awb_gain(awb_gain)
513510

514511
# Sensor-specific settings (try/except for unsupported sensors)
515512
try:
516-
sharpness = prefs.get_int("sharpness", 0)
513+
sharpness = self.prefs.get_int("sharpness", 0)
517514
cam.set_sharpness(sharpness)
518515
except:
519516
pass # Not supported on OV2640
520517

521518
try:
522-
denoise = prefs.get_int("denoise", 0)
519+
denoise = self.prefs.get_int("denoise", 0)
523520
cam.set_denoise(denoise)
524521
except:
525522
pass # Not supported on OV2640
526523

527524
# Advanced corrections
528-
colorbar = prefs.get_bool("colorbar", False)
525+
colorbar = self.prefs.get_bool("colorbar", False)
529526
cam.set_colorbar(colorbar)
530527

531-
dcw = prefs.get_bool("dcw", True)
528+
dcw = self.prefs.get_bool("dcw", True)
532529
cam.set_dcw(dcw)
533530

534-
bpc = prefs.get_bool("bpc", False)
531+
bpc = self.prefs.get_bool("bpc", False)
535532
cam.set_bpc(bpc)
536533

537-
wpc = prefs.get_bool("wpc", True)
534+
wpc = self.prefs.get_bool("wpc", True)
538535
cam.set_wpc(wpc)
539536

540-
raw_gma = prefs.get_bool("raw_gma", True)
537+
raw_gma = self.prefs.get_bool("raw_gma", True)
541538
cam.set_raw_gma(raw_gma)
542539

543-
lenc = prefs.get_bool("lenc", True)
540+
lenc = self.prefs.get_bool("lenc", True)
544541
cam.set_lenc(lenc)
545542

546543
# JPEG quality (only relevant for JPEG format)
547544
try:
548-
quality = prefs.get_int("quality", 85)
545+
quality = self.prefs.get_int("quality", 85)
549546
cam.set_quality(quality)
550547
except:
551548
pass # Not in JPEG mode
@@ -554,4 +551,3 @@ def apply_camera_settings(cam, use_webcam):
554551

555552
except Exception as e:
556553
print(f"Error applying camera settings: {e}")
557-

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,10 @@ class CameraSettingsActivity(Activity):
6767
("1920x1080", "1920x1080"),
6868
]
6969

70+
# These are taken from the Intent:
7071
use_webcam = False
7172
scanqr_mode = False
73+
prefs = None
7274

7375
# Widgets:
7476
button_cont = None
@@ -84,16 +86,14 @@ def __init__(self):
8486
def onCreate(self):
8587
self.scanqr_mode = self.getIntent().extras.get("scanqr_mode")
8688
self.use_webcam = self.getIntent().extras.get("use_webcam")
89+
self.prefs = self.getIntent().extras.get("prefs")
8790
if self.use_webcam:
8891
self.resolutions = self.WEBCAM_RESOLUTIONS
8992
print("Using webcam resolutions")
9093
else:
9194
self.resolutions = self.ESP32_RESOLUTIONS
9295
print("Using ESP32 camera resolutions")
9396

94-
# Load preferences
95-
prefs = SharedPreferences(self.PACKAGE)
96-
9797
# Create main screen
9898
screen = lv.obj()
9999
screen.set_size(lv.pct(100), lv.pct(100))
@@ -106,18 +106,18 @@ def onCreate(self):
106106

107107
# Create Basic tab (always)
108108
basic_tab = tabview.add_tab("Basic")
109-
self.create_basic_tab(basic_tab, prefs)
109+
self.create_basic_tab(basic_tab, self.prefs)
110110

111111
# Create Advanced and Expert tabs only for ESP32 camera
112112
if not self.use_webcam or True: # for now, show all tabs
113113
advanced_tab = tabview.add_tab("Advanced")
114-
self.create_advanced_tab(advanced_tab, prefs)
114+
self.create_advanced_tab(advanced_tab, self.prefs)
115115

116116
expert_tab = tabview.add_tab("Expert")
117-
self.create_expert_tab(expert_tab, prefs)
117+
self.create_expert_tab(expert_tab, self.prefs)
118118

119119
#raw_tab = tabview.add_tab("Raw")
120-
#self.create_raw_tab(raw_tab, prefs)
120+
#self.create_raw_tab(raw_tab, self.prefs)
121121

122122
self.setContentView(screen)
123123

@@ -526,8 +526,7 @@ def erase_and_close(self):
526526

527527
def save_and_close(self):
528528
"""Save all settings to SharedPreferences and return result."""
529-
prefs = SharedPreferences(self.PACKAGE)
530-
editor = prefs.edit()
529+
editor = self.prefs.edit()
531530

532531
# Save all UI control values
533532
for pref_key, control in self.ui_controls.items():

0 commit comments

Comments
 (0)