diff --git a/lib/pbio/drv/display/display_ev3.c b/lib/pbio/drv/display/display_ev3.c index 909ff6f4a..cdc5eb885 100644 --- a/lib/pbio/drv/display/display_ev3.c +++ b/lib/pbio/drv/display/display_ev3.c @@ -486,6 +486,34 @@ uint8_t pbdrv_display_get_max_value(void) { return ST7586S_VALUE_MAX; } +uint8_t pbdrv_display_get_value_from_hsv(uint16_t h, uint8_t s, uint8_t v) { + // Method to compute those values: take a picture of the EV3 screen + // displaying the four gray levels, take a sample for each level, then, + // using python: + // + // import numpy as np + // measures = np.array([28, 36, 41, 47]) # % + // measures = measures - measures[0] + // measures = measures / measures[-1] * 100 * 100 + // splits = (measures[0:-1] + measures[1:]) / 2 + // print([int(x) for x in splits]) + static const uint16_t splits_x100[] = { 2105, 5526, 8421 }; + uint16_t l_x100 = v * (100 - s / 2); + if (l_x100 < splits_x100[1]) { + if (l_x100 < splits_x100[0]) { + return 3; + } else { + return 2; + } + } else { + if (l_x100 < splits_x100[2]) { + return 1; + } else { + return 0; + } + } +} + void pbdrv_display_update(void) { pbdrv_display_user_frame_update_requested = true; pbio_os_request_poll(); diff --git a/lib/pbio/drv/display/display_virtual.c b/lib/pbio/drv/display/display_virtual.c index dab6f8d5a..b0c1047e4 100644 --- a/lib/pbio/drv/display/display_virtual.c +++ b/lib/pbio/drv/display/display_virtual.c @@ -87,6 +87,25 @@ uint8_t pbdrv_display_get_max_value(void) { return 3; } +uint8_t pbdrv_display_get_value_from_hsv(uint16_t h, uint8_t s, uint8_t v) { + // Method to compute those values: see EV3 driver. + static const uint16_t splits_x100[] = { 2105, 5526, 8421 }; + uint16_t l_x100 = v * (100 - s / 2); + if (l_x100 < splits_x100[1]) { + if (l_x100 < splits_x100[0]) { + return 3; + } else { + return 2; + } + } else { + if (l_x100 < splits_x100[2]) { + return 1; + } else { + return 0; + } + } +} + void pbdrv_display_update(void) { pbdrv_display_user_frame_update_requested = true; pbio_os_request_poll(); diff --git a/lib/pbio/include/pbdrv/display.h b/lib/pbio/include/pbdrv/display.h index 237ca4a25..8021be2da 100644 --- a/lib/pbio/include/pbdrv/display.h +++ b/lib/pbio/include/pbdrv/display.h @@ -26,6 +26,15 @@ pbio_image_t *pbdrv_display_get_image(void); */ uint8_t pbdrv_display_get_max_value(void); +/** + * Get the pixel value corresponding to a color given in HSV space. + * @param [in] h Hue, 0 to 359 degrees. + * @param [in] s Saturation, 0 to 100 percent. + * @param [in] v Value, 0 to 100 percent. + * @return Pixel value. + */ +uint8_t pbdrv_display_get_value_from_hsv(uint16_t h, uint8_t s, uint8_t v); + /** * Update the display to show current content of image container. */ @@ -41,6 +50,10 @@ static inline uint8_t pbdrv_display_get_max_value(void) { return 0; } +static inline uint8_t pbdrv_display_get_value_from_hsv(uint16_t h, uint8_t s, uint8_t v) { + return 0; +} + static inline void pbdrv_display_update(void) { } diff --git a/pybricks/parameters/pb_type_image.c b/pybricks/parameters/pb_type_image.c index 24609f059..42e527c1f 100644 --- a/pybricks/parameters/pb_type_image.c +++ b/pybricks/parameters/pb_type_image.c @@ -44,8 +44,7 @@ static int get_color(mp_obj_t obj) { return mp_obj_get_int(obj); } const pbio_color_hsv_t *hsv = pb_type_Color_get_hsv(obj); - int32_t v = pbio_int_math_bind(hsv->v, 0, 100); - return max - v * max / 100; + return pbdrv_display_get_value_from_hsv(hsv->h, hsv->s, hsv->v); } mp_obj_t pb_type_Image_display_obj_new(void) {