diff --git a/picamera/camera.py b/picamera/camera.py index 36b1202a..af393bb6 100644 --- a/picamera/camera.py +++ b/picamera/camera.py @@ -209,6 +209,7 @@ class PiCamera(object): MAX_FRAMERATE = PiCameraMaxFramerate # modified by PiCamera.__init__ DEFAULT_ANNOTATE_SIZE = 32 CAPTURE_TIMEOUT = 60 + DEFAULT_JUSTIFY = 0 SENSOR_MODES = { 'ov5647': { @@ -3990,7 +3991,7 @@ def _set_annotate_frame_num(self, value): def _get_annotate_text_size(self): self._check_camera_open() - if self._camera.annotate_rev == 3: + if self._camera.annotate_rev >= 3: mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] return mp.text_size or self.DEFAULT_ANNOTATE_SIZE else: @@ -4000,7 +4001,7 @@ def _set_annotate_text_size(self, value): if not (6 <= value <= 160): raise PiCameraValueError( "Invalid annotation text size: %d (valid range 6-160)" % value) - if self._camera.annotate_rev == 3: + if self._camera.annotate_rev >= 3: mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] mp.text_size = value self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] = mp @@ -4020,6 +4021,94 @@ def _set_annotate_text_size(self, value): .. versionadded:: 1.10 """.format(size=DEFAULT_ANNOTATE_SIZE)) + def _get_annotate_justify(self): + self._check_camera_open() + if self._camera.annotate_rev >= 4: + mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] + return mp.justify or self.DEFAULT_ANNOTATE_SIZE + else: + return self.DEFAULT_JUSTIFY + def _set_annotate_justify(self, value): + self._check_camera_open() + if not (0 <= value <= 2): + raise PiCameraValueError( + "Invalid annotation justify value: %d (valid range 0-2)" % value) + if self._camera.annotate_rev >= 4: + mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] + mp.justify = value + self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] = mp + elif value != self.DEFAULT_JUSTIFY: + warnings.warn( + PiCameraFallback( + "Firmware does not support setting text justify; " + "using default (%d) instead" % self.DEFAULT_JUSTIFY)) + annotate_justify = property( + _get_annotate_justify, _set_annotate_justify, doc="""\ + Controls the location of the annotation text. + + The :attr:`annotate_justify` attribute is an int which determines how + the annotation text will aligned on the display. Valid values are + in the range 0 to 2, inclusive. The default is {size}. + + .. versionadded:: 1.10 + """.format(size=DEFAULT_JUSTIFY)) + + def _get_annotate_x_offset(self): + self._check_camera_open() + if self._camera.annotate_rev >= 4: + mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] + return mp.x_offset or 0 + else: + return 0 + def _set_annotate_x_offset(self, value): + self._check_camera_open() + if self._camera.annotate_rev >= 4: + mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] + mp.x_offset = value + self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] = mp + elif value != 0: + warnings.warn( + PiCameraFallback( + "Firmware does not support setting text x_offset; " + "using default (0) instead")) + annotate_x_offset = property( + _get_annotate_x_offset, _set_annotate_x_offset, doc="""\ + Controls the location of the annotation text. + + The :attr:`annotate_x_offset` attribute is an int which determines + the location of the annotation text on the display. + + .. versionadded:: 1.10 + """) + + def _get_annotate_y_offset(self): + self._check_camera_open() + if self._camera.annotate_rev >= 4: + mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] + return mp.y_offset or 0 + else: + return 0 + def _set_annotate_y_offset(self, value): + self._check_camera_open() + if self._camera.annotate_rev >= 4: + mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] + mp.y_offset = value + self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] = mp + elif value != 0: + warnings.warn( + PiCameraFallback( + "Firmware does not support setting text y_offset; " + "using default (0) instead")) + annotate_y_offset = property( + _get_annotate_y_offset, _set_annotate_y_offset, doc="""\ + Controls the location of the annotation text. + + The :attr:`annotate_y_offset` attribute is an int which determines + the location of the annotation text on the display. + + .. versionadded:: 1.10 + """) + def _get_annotate_foreground(self): self._check_camera_open() mp = self._camera.control.params[mmal.MMAL_PARAMETER_ANNOTATE] diff --git a/picamera/mmal.py b/picamera/mmal.py index 81b059fc..4b9d7c32 100644 --- a/picamera/mmal.py +++ b/picamera/mmal.py @@ -1208,6 +1208,36 @@ class MMAL_PARAMETER_CAMERA_ANNOTATE_V3_T(ct.Structure): ('text', ct.c_char * MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN_V3), ] +MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN_V4 = 256 + +class MMAL_PARAMETER_CAMERA_ANNOTATE_V4_T(ct.Structure): + _fields_ = [ + ('hdr', MMAL_PARAMETER_HEADER_T), + ('enable', MMAL_BOOL_T), + ('show_shutter', MMAL_BOOL_T), + ('show_analog_gain', MMAL_BOOL_T), + ('show_lens', MMAL_BOOL_T), + ('show_caf', MMAL_BOOL_T), + ('show_motion', MMAL_BOOL_T), + ('show_frame_num', MMAL_BOOL_T), + ('enable_text_background', MMAL_BOOL_T), + ('custom_background_color', MMAL_BOOL_T), + ('custom_background_Y', ct.c_uint8), + ('custom_background_U', ct.c_uint8), + ('custom_background_V', ct.c_uint8), + ('dummy1', ct.c_uint8), + ('custom_text_color', MMAL_BOOL_T), + ('custom_text_Y', ct.c_uint8), + ('custom_text_U', ct.c_uint8), + ('custom_text_V', ct.c_uint8), + ('text_size', ct.c_uint8), + ('text', ct.c_char * MMAL_CAMERA_ANNOTATE_MAX_TEXT_LEN_V4), + ('justify', ct.c_uint32), # 0=centre, 1=left, 2=right + ('x_offset', ct.c_uint32), # Offset from the justification edge + ('y_offset', ct.c_uint32), + ] + + MMAL_STEREOSCOPIC_MODE_T = ct.c_uint32 # enum ( MMAL_STEREOSCOPIC_MODE_NONE, diff --git a/picamera/mmalobj.py b/picamera/mmalobj.py index ec167f2f..a07d3828 100644 --- a/picamera/mmalobj.py +++ b/picamera/mmalobj.py @@ -2351,6 +2351,7 @@ class MMALCamera(MMALBaseComponent): mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_T, mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V2_T, mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V3_T, + mmal.MMAL_PARAMETER_CAMERA_ANNOTATE_V4_T, ) def __init__(self):