Add custom palettes to draw image with demo

This commit is contained in:
mattdawson 2020-04-23 21:33:01 +12:00
parent cb2d279bda
commit 91efa307e0
4 changed files with 71 additions and 5 deletions

View File

@ -0,0 +1,33 @@
# Draw Image Example with custom color palette
#
# This example shows off how to draw images in the frame buffer with a custom color palette.
import sensor, image, time, pyb
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE) # or GRAYSCALE...
sensor.set_framesize(sensor.QQVGA) # or QQVGA...
sensor.skip_frames(time = 2000)
clock = time.clock()
# the color palette is actually an image, this allows you to use image ops to create palettes
# the image must have 256 entries i.e. 256x1, 64x4, 16x16 and have the format rgb565
palette = image.Image(256,1, sensor.RGB565)
funky_palette = [(0, 0, 0), (255, 255, 247), (255, 255, 247), (255, 255, 239), (255, 255, 239), (255, 255, 230), (255, 255, 230), (255, 251, 214), (255, 251, 214), (255, 251, 206), (255, 251, 206), (255, 247, 189), (255, 247, 189), (255, 247, 181), (255, 247, 181), (255, 247, 165), (255, 247, 165), (255, 247, 165), (255, 243, 148), (255, 243, 148), (255, 243, 132), (255, 243, 132), (255, 243, 115), (255, 243, 115), (255, 239, 99), (255, 239, 99), (255, 239, 90), (255, 239, 90), (255, 235, 74), (255, 235, 74), (255, 231, 66), (255, 231, 66), (255, 231, 49), (255, 231, 49), (255, 231, 49), (255, 227, 41), (255, 227, 41), (255, 223, 33), (255, 223, 33), (255, 223, 25), (255, 223, 25), (255, 219, 16), (255, 219, 16), (255, 215, 8), (255, 215, 8), (255, 210, 8), (255, 210, 8), (255, 206, 8), (255, 206, 8), (255, 206, 0), (255, 206, 0), (255, 206, 0), (255, 202, 0), (255, 202, 0), (255, 198, 0), (255, 198, 0), (255, 194, 0), (255, 194, 0), (255, 190, 0), (255, 190, 0), (255, 186, 0), (255, 186, 0), (255, 182, 0), (255, 182, 0), (255, 178, 0), (255, 178, 0), (255, 174, 0), (255, 174, 0), (255, 174, 0), (255, 170, 0), (255, 170, 0), (255, 170, 0), (255, 170, 0), (255, 162, 0), (255, 162, 0), (255, 158, 0), (255, 158, 0), (255, 154, 0), (255, 154, 0), (247, 150, 0), (247, 150, 0), (247, 146, 0), (247, 146, 0), (247, 142, 0), (247, 142, 0), (247, 142, 0), (247, 138, 0), (247, 138, 0), (247, 138, 0), (247, 138, 0), (247, 134, 0), (247, 134, 0), (247, 130, 0), (247, 130, 0), (247, 125, 0), (247, 125, 0), (247, 121, 0), (247, 121, 0), (247, 117, 0), (247, 117, 0), (247, 113, 0), (247, 113, 0), (247, 113, 0), (239, 109, 0), (239, 109, 0), (239, 105, 0), (239, 105, 0), (239, 101, 0), (239, 101, 0), (239, 101, 0), (239, 101, 0), (239, 97, 0), (239, 97, 0), (239, 93, 8), (239, 93, 8), (239, 89, 8), (239, 89, 8), (239, 85, 8), (239, 85, 8), (239, 85, 8), (239, 81, 8), (239, 81, 8), (230, 77, 8), (230, 77, 8), (230, 77, 16), (230, 77, 16), (230, 73, 16), (230, 73, 16), (230, 69, 25), (230, 69, 25), (230, 65, 33), (230, 65, 33), (222, 61, 41), (222, 61, 41), (222, 57, 58), (222, 57, 58), (222, 57, 58), (222, 53, 66), (222, 53, 66), (222, 49, 74), (222, 49, 74), (222, 45, 90), (222, 45, 90), (214, 40, 99), (214, 40, 99), (214, 36, 107), (214, 36, 107), (214, 32, 107), (214, 32, 107), (214, 28, 115), (214, 28, 115), (206, 24, 123), (206, 24, 123), (206, 24, 123), (206, 24, 123), (206, 24, 123), (206, 20, 132), (206, 20, 132), (197, 16, 132), (197, 16, 132), (197, 12, 140), (197, 12, 140), (197, 12, 140), (197, 12, 140), (189, 8, 148), (189, 8, 148), (189, 4, 148), (189, 4, 148), (189, 4, 148), (189, 4, 148), (189, 4, 148), (181, 4, 148), (181, 4, 148), (181, 0, 148), (181, 0, 148), (181, 0, 148), (181, 0, 148), (173, 0, 148), (173, 0, 148), (173, 0, 156), (173, 0, 156), (165, 0, 156), (165, 0, 156), (165, 0, 156), (165, 0, 156), (156, 0, 156), (156, 0, 156), (156, 0, 156), (148, 0, 156), (148, 0, 156), (148, 0, 156), (148, 0, 156), (140, 0, 156), (140, 0, 156), (132, 0, 156), (132, 0, 156), (132, 0, 156), (132, 0, 156), (123, 0, 156), (123, 0, 156), (115, 0, 156), (115, 0, 156), (107, 0, 156), (107, 0, 156), (107, 0, 156), (107, 0, 156), (107, 0, 156), (99, 0, 156), (99, 0, 156), (90, 0, 156), (90, 0, 156), (82, 0, 148), (82, 0, 148), (74, 0, 148), (74, 0, 148), (74, 0, 148), (74, 0, 148), (66, 0, 148), (66, 0, 148), (58, 0, 148), (58, 0, 148), (58, 0, 148), (58, 0, 140), (58, 0, 140), (49, 0, 140), (49, 0, 140), (41, 0, 140), (41, 0, 140), (33, 0, 132), (33, 0, 132), (25, 0, 132), (25, 0, 132), (16, 0, 123), (16, 0, 123), (16, 0, 115), (16, 0, 115), (8, 0, 115), (8, 0, 115), (8, 0, 115), (8, 0, 107), (8, 0, 107), (0, 0, 99), (0, 0, 99), (0, 0, 90), (0, 0, 90), (0, 0, 82), (0, 0, 82), (0, 0, 66), (0, 0, 66), (0, 0, 49), (0, 0, 49), (0, 0, 33), (0, 0, 33), (0, 0, 0), (0, 0, 0), (0, 0, 0)]
for i in range(0,256):
palette[i] = funky_palette[i]
while(True):
clock.tick()
img = sensor.snapshot()
small_img = img.mean_pooled(4, 4) # Makes a copy.
img.to_rgb565()
x = (img.width()//2)-(small_img.width()//2)
y = (img.height()//2)-(small_img.height()//2)
img.draw_image(small_img, x, y, x_scale=2, y_scale=2, color_palette=palette)
print(clock.fps())

View File

@ -67,6 +67,12 @@ image_t *py_helper_keyword_to_image_mutable_mask(uint n_args, const mp_obj_t *ar
return py_helper_keyword_to_image_mutable(n_args, args, arg_index, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
}
image_t *py_helper_keyword_to_image_mutable_color_palette(uint n_args, const mp_obj_t *args, uint arg_index,
mp_map_t *kw_args)
{
return py_helper_keyword_to_image_mutable(n_args, args, arg_index, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color_palette), NULL);
}
void py_helper_keyword_rectangle(image_t *img, uint n_args, const mp_obj_t *args, uint arg_index,
mp_map_t *kw_args, mp_obj_t kw, rectangle_t *r)
{
@ -124,6 +130,21 @@ int py_helper_keyword_int(uint n_args, const mp_obj_t *args, uint arg_index,
return default_val;
}
int py_helper_keyword_int_maybe(uint n_args, const mp_obj_t *args, uint arg_index,
mp_map_t *kw_args, mp_obj_t kw, int* value)
{
mp_map_elem_t *kw_arg = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP);
if (kw_arg) {
return mp_obj_get_int_maybe(kw_arg->value, value);
} else if (n_args > arg_index) {
return mp_obj_get_int_maybe(args[arg_index], value);
}
return false;
}
float py_helper_keyword_float(uint n_args, const mp_obj_t *args, uint arg_index,
mp_map_t *kw_args, mp_obj_t kw, float default_val)
{
@ -341,3 +362,4 @@ mp_obj_t py_helper_keyword_object(uint n_args, const mp_obj_t *args, uint arg_in
return NULL;
}
}

View File

@ -20,13 +20,17 @@ image_t *py_helper_arg_to_image_color(const mp_obj_t arg);
image_t *py_helper_keyword_to_image_mutable(uint n_args, const mp_obj_t *args, uint arg_index,
mp_map_t *kw_args, mp_obj_t kw, image_t *default_val);
image_t *py_helper_keyword_to_image_mutable_mask(uint n_args, const mp_obj_t *args, uint arg_index,
mp_map_t *kw_args);
mp_map_t *kw_args);
image_t *py_helper_keyword_to_image_mutable_color_palette(uint n_args, const mp_obj_t *args, uint arg_index,
mp_map_t *kw_args);
void py_helper_keyword_rectangle(image_t *img, uint n_args, const mp_obj_t *args, uint arg_index,
mp_map_t *kw_args, mp_obj_t kw, rectangle_t *r);
void py_helper_keyword_rectangle_roi(image_t *img, uint n_args, const mp_obj_t *args, uint arg_index,
mp_map_t *kw_args, rectangle_t *r);
int py_helper_keyword_int(uint n_args, const mp_obj_t *args, uint arg_index,
mp_map_t *kw_args, mp_obj_t kw, int default_val);
int py_helper_keyword_int_maybe(uint n_args, const mp_obj_t *args, uint arg_index,
mp_map_t *kw_args, mp_obj_t kw, int* value);
float py_helper_keyword_float(uint n_args, const mp_obj_t *args, uint arg_index,
mp_map_t *kw_args, mp_obj_t kw, float default_val);
void py_helper_keyword_int_array(uint n_args, const mp_obj_t *args, uint arg_index,

View File

@ -1931,11 +1931,10 @@ STATIC mp_obj_t py_image_draw_image(uint n_args, const mp_obj_t *args, mp_map_t
PY_ASSERT_TRUE_MSG((0 <= arg_alpha) && (arg_alpha <= 256), "Error: 0 <= alpha <= 256!");
image_t *arg_msk =
py_helper_keyword_to_image_mutable_mask(n_args, args, offset + 3, kw_args);
int palette = py_helper_keyword_int(n_args, args, offset + 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color_palette), -1);
const uint16_t *color_palette = NULL;
if (palette != -1) {
int palette;
if (py_helper_keyword_int_maybe(n_args, args, offset + 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_color_palette), &palette)) {
if (palette == COLOR_PALETTE_RAINBOW) {
color_palette = rainbow_table;
} else if (palette == COLOR_PALETTE_IRONBOW) {
@ -1946,6 +1945,14 @@ STATIC mp_obj_t py_image_draw_image(uint n_args, const mp_obj_t *args, mp_map_t
if (arg_other->bpp != IMAGE_BPP_GRAYSCALE) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Can only specify color palette when passing a grayscale image!"));
}
else {
image_t *arg_palette = py_helper_keyword_to_image_mutable_color_palette(n_args, args, offset + 4, kw_args);
if (arg_palette) {
if (arg_palette->bpp != IMAGE_BPP_RGB565) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Palette must be an RGB565 format image!"));
if ((arg_palette->w * arg_palette->h) != 256) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Palette image must have 256 pixels!"));
color_palette = (uint16_t*)arg_palette->data;
}
}
imlib_draw_image(arg_img, arg_other, arg_cx, arg_cy, arg_x_scale, arg_y_scale, arg_alpha, arg_msk, color_palette);
return args[0];