Bokeh image format standards and interoperability

My slightly longer version with an additional button to turn periodic callbacks on and off for continuous rotations. Both buttons work to increase the image rotation angle.

from base64 import b64decode
import sys

import cv2
import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Button
from bokeh.plotting import figure

import imutils # rotate_bound()

T_update = 200 # (ms) browser update rate specified in add_periodic_callback()
current_angle = 0

img_jpeg = b64decode(
    'iVBORw0KGgoAAAANSUhEUgAAADIAAAAOBAMAAACfqVJUAAAAHlBMVEUAAAAAAwCKLY3jF17xWyICq65Qlc8js1T2qhmnzTbxGUeMAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAACVSURBVBjTpY89DsIwDIWfRRF087sB6sCMyhHIAbp078TMgroy9gq5LXYSooqOfYqsF3+Jf0BU6c9IcjvI6bUlJiDO78EJIXYVJRXptHEeRyP22PPC7Cy2EUcnKQOmkPrwHIHnpNQNWT5OvLi1oa7/LMB1ouZqqES0CUCXm6+Iz9aER9/5bKyYZZ9w7y91n0KKDjf86QvVrhIPSsvLCwAAAABJRU5ErkJggg==')
arr = np.fromstring(img_jpeg, np.uint8)
frame = cv2.imdecode(arr, cv2.IMREAD_UNCHANGED)
orig_img = frame[::-1].copy().view(dtype=np.uint32)


pw = 5*orig_img.shape[0]
ph = 5*orig_img.shape[1]
current_angle = 0
p = figure(aspect_ratio=1, x_range=(0, pw), y_range=(0, ph))


def mk_data(image):
    ih, iw, _ = image.shape
    return dict(image=[image], dw=[iw], dh=[ih], x=[(pw - iw) / 2], y=[(ph - ih) / 2])


src = ColumnDataSource(data=mk_data(orig_img))
p.image_rgba(image='image', x='x', y='y', dw='dw', dh='dh', source=src)


b1 = Button(label='Rotate once!')

def rotate_img_by_15_deg():
    global current_angle
    current_angle += 15
    img = imutils.rotate_bound(orig_img.view(dtype=np.uint8), current_angle) # use imutils with cv2 format image
    src.data = mk_data(img.view(dtype=np.uint32)) # re-create attributes for bokeh using updated image

def callback_button():
    global periodic_cb_id
    if b2.label == 'Press to: > Play':
        print('adding add_periodic_callback()')
        b2.label = 'Press to: = Pause'
        periodic_cb_id = curdoc().add_periodic_callback(callback_update_data, T_update) # <-- this controls update frequency
    else:
        print('removing add_periodic_callback()')
        b2.label = 'Press to: > Play'
        curdoc().remove_periodic_callback( periodic_cb_id )

def callback_update_data():
    global current_angle
    current_angle += 1
    sys.stdout.flush()
    img = imutils.rotate_bound(orig_img.view(dtype=np.uint8), current_angle) # use imutils with cv2 formated (.view'ed) image
    src.data = mk_data(img.view(dtype=np.uint32)) # re-create all image attributes for bokeh using updated img


b1.on_click(rotate_img_by_15_deg)

b2 = Button(label='Press to: > Play')
b2.on_click(callback_button)


curdoc().add_root(column(p, b1, b2))

Run with:
bokeh serve --show rotate_img_callbacks.py