import streamlit as st import cv2 import numpy as np from PIL import Image import base64 color_step = st.slider('color_step', value=10, min_value=1, max_value=179, step=1) #duration of each frame of the gif in milliseconds duration_parameter = st.slider('duration_parameter aka duration of each frame of the gif in milliseconds', value=10, min_value=1, max_value=2000, step=10) #Loop parameter = number of times gif loops. 0 = loops infinitely. loop_parameter = st.slider('Loop parameter aka number of times gif loops', value=0, min_value=0, max_value=10, step=1) if color_step == 0: my_hue_list = [0] else: my_hue_list = list( range(0, 180, color_step) ) #Color step basically gives step range of this list, ie if color_step = 2 then it is [0,2,4,6,....,178] user_image_object = st.file_uploader("upload your image", type=['png', 'jpg'], accept_multiple_files=False) if user_image_object is not None: st.image(user_image_object ) user_image_name = "input_image.png" #re-encode for streamlit interface #streamlit uploader encodes as a pillow img so we want to save to open in cv2 (converting directly is a pain) input_image = Image.open( user_image_object ) input_image.save(user_image_name ) # load image with alpha channel img = cv2.imread( user_image_name , cv2.IMREAD_UNCHANGED) # extract alpha channel #alpha = img[:,:,3] # extract bgr channels bgr = img[:,:,0:3] # convert to HSV hsv = cv2.cvtColor(bgr, cv2.COLOR_BGR2HSV) #h = hsv[:,:,0] #s = hsv[:,:,1] #v = hsv[:,:,2] h,s,v = cv2.split(hsv) if color_step == 0: my_hue_list = [0] else: my_hue_list = list( range(0, 180, color_step) ) #Color step basically gives step range of this list, ie if color_step = 2 then it is [0,2,4,6,....,178] #180 at end means highest it can go is 179 (same as hue param ) #including 0 makes original image part of the outputs/gif #H,S,V = Hue , Saturation, Value (ie color value) parameters #Hue has range [0,179] , Saturation [0,255] , Value [0,255] img_array = [] output_filename_array = [] for i in my_hue_list: # modify hue channel by adding difference and modulo 180 (modulo because hue parameter only goes up to index 180, shouldn't exceed that ) hnew = np.mod(h + i, 180).astype(np.uint8) #<<<<<<<<<<<<<<<< where the iter comes in # recombine channels hsv_new = cv2.merge([hnew,s,v]) # convert back to bgr bgr_new = cv2.cvtColor(hsv_new, cv2.COLOR_HSV2BGR) img_array.append(bgr_new ) # put alpha back into bgr_new #bgra = cv2.cvtColor(bgr_new, cv2.COLOR_BGR2BGRA) #bgra[:,:,3] = alpha # save output AS FILE LABELED BY ITERABLE output_filename = 'output_bgr_new_' + str(i) +'.png' #<<<<<<<<<<<<<<<< where the iter comes in output_filename_array.append(output_filename) cv2.imwrite(output_filename, bgr_new) height, width, layers = bgr_new.shape size = (width,height) st.write("len(img_array) = ", len(img_array) ) '''Show some demos: ''' #Uncomment this if to show some sample images of the gif if len(img_array) > 7: for ii in [1, 4, 7]: st.image( img_array[ii] ) #HuggingFaces Spaces can create a video vile ephemerally but doesn't actually save one that we can access. #So to show the video/gif we save it as a file then open that file to show it in streamlit st.text("Generating GIF, may take a minute") #Create GIF img, *imgs = [Image.open(f) for f in output_filename_array] img.save(fp="output_gif.gif", format='GIF', append_images=imgs, save_all=True, duration=duration_parameter, loop=loop_parameter) #Show gif using this script to show gifs in streamlit https://discuss.streamlit.io/t/how-to-show-local-gif-image/3408/2 """### gif from local file""" file_ = open("output_gif.gif", "rb") contents = file_.read() data_url = base64.b64encode(contents).decode("utf-8") file_.close() st.markdown( f'output gif', unsafe_allow_html=True, )