def _prepare(self) -> None: self.should_prepare = False import numpy as np # pi3d has to be imported in the same thread that it will draw in # Thus, import it here instead of at the top of the file import pi3d from pi3d.util.OffScreenTexture import OffScreenTexture from pi3d.constants import ( opengles, GL_CLAMP_TO_EDGE, GL_ALWAYS, ) # used for reimplementing the draw call with instancing from pi3d.constants import ( GLsizei, GLint, GLboolean, GL_FLOAT, GLuint, GL_ARRAY_BUFFER, GL_STATIC_DRAW, GLfloat, ) from PIL import Image # Setup display and initialise pi3d self.display = pi3d.Display.create(w=self.width, h=self.height, window_title="Raveberry") # error 0x500 after Display create # error = opengles.glGetError() # Set a pink background color so mistakes are clearly visible # self.display.set_background(1, 0, 1, 1) self.display.set_background(0, 0, 0, 1) # print OpenGL Version, useful for debugging # import ctypes # def print_char_p(addr): # g = (ctypes.c_char*32).from_address(addr) # i = 0 # while True: # c = g[i] # if c == b'\x00': # break # sys.stdout.write(c.decode()) # i += 1 # sys.stdout.write('\n') # print_char_p(opengles.glGetString(GL_VERSION)) # Visualization is split into five parts: # The background, the particles, the spectrum, the logo and after effects. # * The background is a vertical gradient that cycles through HSV color space, # speeding up with strong bass. # * Particles are multiple sprites that are created at a specified x,y-coordinate # and fly towards the camera. # Due to the projection into screenspace they seem to move away from the center. # * The spectrum is a white circle that represents the fft-transformation of the # currently played audio. It is smoothed to avoid strong spikes. # * The logo is a black circle on top of the spectrum containing the logo. # * After effects add a vignette. # Each of these parts is represented with pi3d Shapes. # They have their own shader and are ordered on the z-axis to ensure correct overlapping. background_shader = pi3d.Shader( os.path.join(settings.BASE_DIR, "core/lights/circle/background")) self.background = pi3d.Sprite(w=2, h=2) self.background.set_shader(background_shader) self.background.positionZ(0) self.particle_shader = pi3d.Shader( os.path.join(settings.BASE_DIR, "core/lights/circle/particle")) # create one sprite for all particles self.particle_sprite = pi3d.Sprite(w=self.PARTICLE_SIZE, h=self.PARTICLE_SIZE) self.particle_sprite.set_shader(self.particle_shader) self.particle_sprite.positionZ(0) # this array containes the position and speed for all particles particles = self._initial_particles() # This part was modified from https://learnopengl.com/Advanced-OpenGL/Instancing self.instance_vbo = GLuint() opengles.glGenBuffers(GLsizei(1), ctypes.byref(self.instance_vbo)) opengles.glBindBuffer(GL_ARRAY_BUFFER, self.instance_vbo) particles_raw = particles.ctypes.data_as(ctypes.POINTER(GLfloat)) opengles.glBufferData(GL_ARRAY_BUFFER, particles.nbytes, particles_raw, GL_STATIC_DRAW) opengles.glBindBuffer(GL_ARRAY_BUFFER, GLuint(0)) attr_particle = opengles.glGetAttribLocation( self.particle_shader.program, b"particle") opengles.glEnableVertexAttribArray(attr_particle) opengles.glBindBuffer(GL_ARRAY_BUFFER, self.instance_vbo) opengles.glVertexAttribPointer(attr_particle, GLint(4), GL_FLOAT, GLboolean(0), 0, 0) opengles.glBindBuffer(GL_ARRAY_BUFFER, GLuint(0)) opengles.glVertexAttribDivisor(attr_particle, GLuint(1)) spectrum_shader = pi3d.Shader( os.path.join(settings.BASE_DIR, "core/lights/circle/spectrum")) # use the ratio to compute small sizes for the sprites ratio = self.width / self.height self.spectrum = pi3d.Sprite(w=2 / ratio, h=2) self.spectrum.set_shader(spectrum_shader) self.spectrum.positionZ(0) # initialize the spectogram history with zeroes self.fft = np.zeros( (self.FFT_HIST, self.cava.bars - 2 * self.SPECTRUM_CUT), dtype=np.uint8) logo_shader = pi3d.Shader( os.path.join(settings.BASE_DIR, "core/lights/circle/logo")) self.logo = pi3d.Sprite(w=1.375 / ratio, h=1.375) self.logo.set_shader(logo_shader) self.logo.positionZ(0) logo_image = Image.open( os.path.join(settings.STATIC_ROOT, "graphics/raveberry_square.png")) self.logo_array = np.frombuffer(logo_image.tobytes(), dtype=np.uint8) self.logo_array = self.logo_array.reshape( (logo_image.size[1], logo_image.size[0], 3)) # add space for the spectrum self.logo_array = np.concatenate( ( self.logo_array, np.zeros( (self.FFT_HIST, logo_image.size[0], 3), dtype=np.uint8), ), axis=0, ) # add alpha channel self.logo_array = np.concatenate( ( self.logo_array, np.ones( (self.logo_array.shape[0], self.logo_array.shape[1], 1), dtype=np.uint8, ), ), axis=2, ) # In order to save memory, the logo and the spectrum share one texture. # The upper 256x256 pixels are the raveberry logo. # Below are 256xFFT_HIST pixels for the spectrum. # The lower part is periodically updated every frame while the logo stays static. self.dynamic_texture = pi3d.Texture(self.logo_array) # Prevent interpolation from opposite edge self.dynamic_texture.m_repeat = GL_CLAMP_TO_EDGE self.spectrum.set_textures([self.dynamic_texture]) self.logo.set_textures([self.dynamic_texture]) after_shader = pi3d.Shader( os.path.join(settings.BASE_DIR, "core/lights/circle/after")) self.after = pi3d.Sprite(w=2, h=2) self.after.set_shader(after_shader) self.after.positionZ(0) # create an OffscreenTexture to allow scaling. # By first rendering into a smaller Texture a lot of computation is saved. # This OffscreenTexture is then drawn at the end of the draw loop. self.post = OffScreenTexture("scale") self.post_sprite = pi3d.Sprite(w=2, h=2) post_shader = pi3d.Shader( os.path.join(settings.BASE_DIR, "core/lights/circle/scale")) self.post_sprite.set_shader(post_shader) self.post_sprite.set_textures([self.post]) self.total_bass = 0 self.last_loop = time.time() self.time_elapsed = 0 opengles.glDepthFunc(GL_ALWAYS)
def __init__(self, gui, x, y, width, start_val=None, callback=None, label=None, label_pos='left', shortcut=None): """This consists of four Shapes but the first one is duplicated so the Widget.draw() method can be used unchanged. The images are hard coded so no list of Shapes or images needs to be supplied however arguments additional to those for Widget are *width* width of the scroll (excluding buttons on either end) *start_val* proportion of the way across i.e. if width = 200 then start_val of 150 would be three quarters NB the callback is called with *args equal to the position of the slider so the function needs to be defined with this in mind i.e. ``def cb(*args):`` args will then be available as a tuple (0.343,) """ imgs = [ "scroll.gif", "scroll.gif", "scroll_lh.gif", "scroll_rh.gif", "scroll_thumb.gif" ] shapes = [] end_w = 0 for i, im in enumerate(imgs): tex = pi3d.Texture(gui.icon_path + im, blend=True, mipmap=False) w = tex.ix if i > 0 else width if i == 2: end_w = tex.ix #offsets for end buttons if i == 4: thumb_w = tex.ix / 2.0 #offset for thumb shape = pi3d.Sprite(camera=gui.camera, w=w, h=tex.iy, z=2.0) shape.set_draw_details(gui.shader, [tex]) shapes.append(shape) super(Scrollbar, self).__init__(gui, shapes, x, y, callback=callback, label=label, label_pos=label_pos, shortcut=shortcut) self.toggle = False self.t_stop = [self.bounds[0] + thumb_w, self.bounds[2] - thumb_w] if start_val is None: start_val = width / 2.0 self.thumbpos = start_val / width * (self.t_stop[1] - self.t_stop[0]) self.shapes[4].positionX(self.t_stop[0] + self.thumbpos) self.shapes[4].translateZ(-0.1) self.shapes[2].translateX((-width - end_w) / 2.0) self.shapes[3].translateX((width + end_w) / 2.0) self.bounds[0] -= end_w self.bounds[2] += end_w if self.labelobj is not None: if label_pos == 'left': self.labelobj.translateX(-end_w) elif label_pos == 'right': self.labelobj.translateX(end_w)
def __init__(self, config): # noinspection PyBroadException try: locale.setlocale(locale.LC_TIME, config.local) except Exception as e: log.warning("error trying to set local to {}".format(config.local), e) self._display = pi3d.Display.create( x=config.display_x, y=config.display_y, w=config.display_w, h=config.display_h, frames_per_second=config.fps, display_config=pi3d.DISPLAY_CONFIG_HIDE_CURSOR, background=config.background, ) self._camera = pi3d.Camera(is_3d=False) shader = pi3d.Shader(config.shader) self._slide = pi3d.Sprite( camera=self._camera, w=self._display.width, h=self._display.height, z=5.0 ) self._slide.set_shader(shader) self._slide.unif[47] = config.edge_alpha self._slide.unif[54] = config.blend_type self._slide.unif[55] = 1.0 # brightness used by shader [18][1] if config.keyboard: self.keyboard = pi3d.Keyboard() grid_size = math.ceil(len(config.codepoints) ** 0.5) font = pi3d.Font( config.font_file, codepoints=config.codepoints, grid_size=grid_size ) self._text = pi3d.PointText( font, self._camera, max_chars=200, point_size=config.show_text_sz ) self._textblock = pi3d.TextBlock( x=0, y=-self._display.height // 2 + (config.show_text_sz // 2) + 20, z=0.1, rot=0.0, char_count=199, text_format="{}".format(" "), size=0.99, spacing="F", justify=0.5, space=0.02, colour=(1.0, 1.0, 1.0, 1.0), ) self._text.add_text_block(self._textblock) bkg_ht = self._display.height // 4 text_bkg_array = np.zeros((bkg_ht, 1, 4), dtype=np.uint8) text_bkg_array[:, :, 3] = np.linspace(0, 170, bkg_ht).reshape(-1, 1) text_bkg_tex = pi3d.Texture(text_bkg_array, blend=True, free_after_load=True) self._text_bkg = pi3d.Plane( w=self._display.width, h=bkg_ht, y=-self._display.height // 2 + bkg_ht // 2, z=4.0, ) back_shader = pi3d.Shader("uv_flat") self._text_bkg.set_draw_details(back_shader, [text_bkg_tex]) self._foreground_slide = None self._background_slide = None
client.subscribe("frame/fade_time", qos=0) client.subscribe("frame/shuffle", qos=0) client.subscribe("frame/quit", qos=0) client.subscribe("frame/paused", qos=0) client.subscribe("frame/back", qos=0) client.on_connect = on_connect client.on_message = on_message except Exception as e: print("MQTT not set up because of: {}".format(e)) ############################################## DISPLAY = pi3d.Display.create(frames_per_second=FPS, background=BACKGROUND) CAMERA = pi3d.Camera(is_3d=False) shader = pi3d.Shader("/home/pi/pi3d_demos/shaders/blend_new") slide = pi3d.Sprite(camera=CAMERA, w=DISPLAY.width, h=DISPLAY.height, z=5.0) slide.set_shader(shader) slide.unif[47] = EDGE_ALPHA #inserted BME if INTERACTIVE: kbd = pi3d.Keyboard() # images in iFiles list nexttm = 0.0 iFiles, nFi = get_files(date_from, date_to) next_pic_num = 0 sfg = None # slide for background sbg = None # slide for foreground if nFi == 0: print('No files selected!')
flatsh = pi3d.Shader("uv_flat") defocus = pi3d.Defocus() #Create textures shapeimg = pi3d.Texture("textures/straw1.jpg") shapebump = pi3d.Texture("textures/floor_nm.jpg") shapeshine = pi3d.Texture("textures/pong3.png") #Create shape myshape = pi3d.MergeShape(camera=persp_cam) #specify perspective view asphere = pi3d.Sphere(sides=16, slices=16) myshape.radialCopy(asphere, step=72) myshape.position(0.0, 0.0, 5.0) myshape.set_draw_details(shader, [shapeimg, shapebump, shapeshine], 8.0, 0.1) mysprite = pi3d.Sprite(w=10.0, h=10.0, camera=persp_cam) mysprite.position(0.0, 0.0, 15.0) mysprite.set_draw_details(flatsh, [shapebump]) tick=0 next_time = time.time()+2.0 #load ttf font and set the font colour to 'raspberry' arialFont = pi3d.Font("fonts/NotoSerif-Regular.ttf", (221,0,170,255), add_codepoints=[256]) arialFont.blend = True #much better anitaliased look but must String.draw() after everything else mystring = pi3d.String(font=arialFont, string=MESSAGE, camera=ortho_cam, z=1.0, is_3d=False, justify="r") # orthographic view mystring.set_shader(flatsh) # Fetch key presses.
if config.VERBOSE: print("MQTT not set up because of: {}".format( e)) # sometimes starts paused ############################################## DISPLAY = pi3d.Display.create(x=config.DISPLAY_X, y=config.DISPLAY_Y, w=config.DISPLAY_W, h=config.DISPLAY_H, frames_per_second=config.FPS, display_config=pi3d.DISPLAY_CONFIG_HIDE_CURSOR, background=config.BACKGROUND) CAMERA = pi3d.Camera(is_3d=False) shader = pi3d.Shader(config.SHADER) slide = pi3d.Sprite(camera=CAMERA, w=DISPLAY.width, h=DISPLAY.height, z=5.0) slide.set_shader(shader) slide.unif[47] = config.EDGE_ALPHA slide.unif[54] = config.BLEND_TYPE if config.KEYBOARD: kbd = pi3d.Keyboard() # images in iFiles list nexttm = 0.0 iFiles, nFi = get_files(date_from, date_to) next_pic_num = 0 sfg = None # slide for background sbg = None # slide for foreground # PointText and TextBlock. If SHOW_TEXT_TM <= 0 then this is just used for no images message
def main( startdir, # Root folder for images, with recursive search config_file, # File with list of file names (for fast restart) interval, # Seconds between images shuffle, # True or False geonamesuser, # User name for GeoNames server www.geonames.org check_dirs # Interval between checking folders in seconds ) : global backup_dir,paused,geoloc,last_file_change,kb_up,FIT,BLUR_EDGES # backup_dir = os.path.abspath(os.path.join(startdir,config.BKUP_DIR)) backup_dir = config.BKUP_DIR print(startdir) #print(config.BKUP_DIR) #print(backup_dir) if config.BUTTONS: pause_button = Button(8, hold_time=5) back_button = Button(9, hold_time=5) forward_button = Button(4,hold_time=5) pause_button.when_pressed = handle_press back_button.when_pressed = handle_press pause_button.when_held=handle_hold back_button.when_held=handle_hold forward_button.when_pressed=handle_press forward_button.when_held=handle_hold rotate_button = Button(5, hold_time=5) rotate_button.when_pressed= handle_press rotate_button.when_held=handle_hold paused=False next_check_tm=time.time()+check_dirs time_dot=True ############################################## # Create GeoNames locator object www.geonames.org geoloc=None try: geoloc=GeoNames(username=geonamesuser) except: print("Geographic information server not available") print("Setting up display") DISPLAY = pi3d.Display.create(x=0, y=0, frames_per_second=FPS,display_config=pi3d.DISPLAY_CONFIG_HIDE_CURSOR, background=BACKGROUND) CAMERA = pi3d.Camera(is_3d=False) print(DISPLAY.opengl.gl_id) shader = pi3d.Shader(config.PI3DDEMO + "/shaders/blend_new") #shader = pi3d.Shader("/home/patrick/python/pi3d_demos/shaders/blend_new") slide = pi3d.Sprite(camera=CAMERA, w=DISPLAY.width, h=DISPLAY.height, z=5.0) slide.set_shader(shader) slide.unif[47] = config.EDGE_ALPHA if KEYBOARD: kbd = pi3d.Keyboard() # images in iFiles list nexttm = 0.0 iFiles, nFi = get_files(startdir,config_file,shuffle) next_pic_num = 0 sfg = None # slide for foreground sbg = None # slide for background if nFi == 0: print('No files selected!') exit() # PointText and TextBlock. #font = pi3d.Font(FONT_FILE, codepoints=CODEPOINTS, grid_size=7, shadow_radius=4.0,shadow=(128,128,128,12)) grid_size = math.ceil(len(config.CODEPOINTS) ** 0.5) font = pi3d.Font(config.FONT_FILE, codepoints=config.CODEPOINTS, grid_size=grid_size, shadow_radius=4.0,shadow=(0,0,0,128)) text = pi3d.PointText(font, CAMERA, max_chars=200, point_size=50) text2 = pi3d.PointText(font, CAMERA, max_chars=8, point_size=50) #text = pi3d.PointText(font, CAMERA, max_chars=200, point_size=50) textblock = pi3d.TextBlock(x=-DISPLAY.width * 0.5 + 20, y=-DISPLAY.height * 0.4, z=0.1, rot=0.0, char_count=199, text_format="{}".format(" "), size=0.65, spacing="F", space=0.02, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(textblock) timeblock = pi3d.TextBlock(x=DISPLAY.width*0.5 - 150, y=DISPLAY.height * 0.5 - 50, z=0.1, rot=0.0, char_count=6, text_format="{}".format(" "), size=0.65, spacing="F", space=0.02, colour=(1.0, 1.0, 1.0, 1.0)) text2.add_text_block(timeblock) #Retrieve last image number to restart the slideshow from config.num file #Retrieve next directory check time cacheddata=(0,0,last_file_change,next_check_tm) try: with open(config_file+".num",'r') as f: cacheddata=json.load(f) num_run_through=cacheddata[0] next_pic_num=cacheddata[1] last_file_change=cacheddata[2] next_check_tm=cacheddata[3] except: num_run_through=0 next_pic_num=0 if (next_check_tm < time.time()) : #if stored check time is in the past, make it "now" next_check_tm = time.time() print("Start time ",time.strftime(config.TIME_FORMAT,time.localtime())) print("Next Check time ",time.strftime(config.TIME_FORMAT,time.localtime(next_check_tm))) print("Starting with round number ",num_run_through) print("Starting with picture number ",next_pic_num) tm=time.time() pic_num=next_pic_num # Main loop while DISPLAY.loop_running(): previous = tm # record previous time value, used to make cursor blink tm = time.time() if (time.localtime(previous).tm_sec < time.localtime(tm).tm_sec) : #blink dot time_dot = not(time_dot) #check if there are file to display if nFi > 0: # If needed, display new photo if (tm > nexttm and not paused) or (tm - nexttm) >= 86400.0: # this must run first iteration of loop print("tm es ",tm," nexttm es ", nexttm, " la resta ", tm-nexttm) nexttm = tm + interval a = 0.0 # alpha - proportion front image to back sbg = sfg sfg = None while sfg is None: # keep going through until a usable picture is found TODO break out how? # Calculate next picture index to be shown pic_num = next_pic_num next_pic_num += 1 if next_pic_num >= nFi: num_run_through += 1 next_pic_num = 0 #update persistent cached data for restart cacheddata=(num_run_through,pic_num,last_file_change,next_check_tm) with open(config_file+".num","w") as f: json.dump(cacheddata,f,separators=(',',':')) # File Open and texture build try: temp=time.time() im = Image.open(iFiles[pic_num]) print("foto numero ",pic_num," time ",time.time()) except: print("Error Opening File",iFiles[pic_num]) continue # EXIF data and geolocation analysis # define some default values orientation = 1 # unrotated dt=None # will hold date from EXIF datestruct=None # will hold formatted date # Format metadata try: exif_data = im._getexif() except: exif_data=None try: orientation = int(exif_data[config.EXIF_ORIENTATION]) except: orientation = 1 try: dt = time.mktime(time.strptime(exif_data[config.EXIF_DATID], '%Y:%m:%d %H:%M:%S')) datestruct=time.localtime(dt) except: datestruct=None try: location = get_geo_name(exif_data) except Exception as e: # NB should really check error print('Error preparing geoname: ', e) location = None # Load and format image try: sfg = tex_load(im, orientation, (DISPLAY.width, DISPLAY.height)) except: next_pic_num += 1 # skip to next photo continue nexttm = tm+interval #Time points to next interval # Image Rendering if sbg is None: # first time through sbg = sfg slide.set_textures([sfg, sbg]) slide.unif[45:47] = slide.unif[42:44] # transfer front width and height factors to back slide.unif[51:53] = slide.unif[48:50] # transfer front width and height offsets wh_rat = (DISPLAY.width * sfg.iy) / (DISPLAY.height * sfg.ix) if (wh_rat > 1.0 and FIT) or (wh_rat <= 1.0 and not FIT): sz1, sz2, os1, os2 = 42, 43, 48, 49 else: sz1, sz2, os1, os2 = 43, 42, 49, 48 wh_rat = 1.0 / wh_rat slide.unif[sz1] = wh_rat slide.unif[sz2] = 1.0 slide.unif[os1] = (wh_rat - 1.0) * 0.5 slide.unif[os2] = 0.0 #transition if KENBURNS: xstep, ystep = (slide.unif[i] * 2.0 / interval for i in (48, 49)) slide.unif[48] = 0.0 slide.unif[49] = 0.0 kb_up = not kb_up # Prepare the different texts to be shown overlay_text= "" #this will host the text on screen if SHOW_LOCATION: #(and/or month-year) if location is not None: overlay_text += tidy_name(str(location)) #print(overlay_text) if datestruct is not None : overlay_text += " " + tidy_name(config.MES[datestruct.tm_mon - 1]) + "-" + str(datestruct.tm_year) #print(overlay_text) try: textblock.set_text(text_format="{}".format(overlay_text)) text.regen() except : #print("Wrong Overlay_text Format") textblock.set_text(" ") # print time on screen, blink separator every second if not paused : timetext=timetostring(time_dot,tm) else : timetext="PAUSA" timeblock.set_text(text_format="{}".format(timetext)) # manages transition if KENBURNS: t_factor = nexttm - tm if kb_up: t_factor = interval - t_factor slide.unif[48] = xstep * t_factor slide.unif[49] = ystep * t_factor if a <= 1.0: # transition is happening a += delta_alpha slide.unif[44] = a else: # Check if image files list has to be rebuilt (no transition on going, so no harm to image slide.set_textures([sfg, sfg]) if (num_run_through > config.NUMBEROFROUNDS) or (time.time() > next_check_tm) : #re-load images after running through them or exceeded time print("Refreshing Files list") next_check_tm = time.time() + check_dirs # Set up the next interval try: if check_changes(startdir): #rebuild files list if changes happened print("Re-Fetching images files, erase config file") with open(config_file,'w') as f : json.dump('',f) # creates an empty config file, forces directory reload iFiles, nFi = get_files(startdir,config_file,shuffle) next_pic_num = 0 else : print("No directory changes: do nothing") except: print("Error refreshing file list, keep old one") num_run_through = 0 #render the image slide.draw() #render the text text.draw() text2.draw() else: textblock.set_text("NO IMAGES SELECTED") textblock.colouring.set_colour(alpha=1.0) text.regen() text.draw() # Keyboard and button handling #delta=time.time()-86400.0 delta=0 if KEYBOARD: k = kbd.read() if k != -1: print("Key pressed", tm-nexttm) #nexttm = delta # print(tm - nexttm) if k==27 or quit: #ESC break if k==ord(' '): paused = not paused if k==ord('s'): # go back a picture nexttm = 0 next_pic_num -= 2 if next_pic_num < -1: next_pic_num = -1 nexttm = delta if k==ord('q'): #go forward nexttm = delta if k==ord('r') and paused: # rotate picture (only if paused) nexttm = delta im.close() #close file on disk try: with open(iFiles[pic_num],'rb') as tmp_file: #open file again to be used in exif context tmp_im = exif.Image(tmp_file) tmp_file.close() if (tmp_im.has_exif) : # If it has exif data, rotate it if it does not, do nothing save_file(iFiles[pic_num]) # Copy file to Backup folder tmp_im.orientation = rotate90CW(tmp_im.orientation) # changes EXIF data orientation parameter with open(iFiles[pic_num],'wb') as tmp_file: # Write the file with new exif orientation tmp_file.write(tmp_im.get_file()) next_pic_num -=1 # force reload on screen except: print("Error when rotating photo") # nexttm = delta if config.BUTTONS: #Handling of config.BUTTONS goes here if paused and (rotate_button.estado == 1 or rotate_button.estado == 2): # Need to be on pause rotate_button.estado = 0 nexttm = delta im.close() #close file on disk try: with open(iFiles[pic_num],'rb') as tmp_file: #open file again to be used in exif context tmp_im = exif.Image(tmp_file) tmp_file.close() if (tmp_im.has_exif) : # If it has exif data, rotate it if it does not, do nothing save_file(iFiles[pic_num]) # Copy file to Backup folder tmp_im.orientation = rotate90CW(tmp_im.orientation) # changes EXIF data orientation parameter with open(iFiles[pic_num],'wb') as tmp_file: # Write the file with new exif orientation tmp_file.write(tmp_im.get_file()) next_pic_num -=1 # force reload on screen except: print("Error when rotating photo") if pause_button.estado == 1 or pause_button.estado == 2 : # button was pressed #nexttm = delta paused = not paused pause_button.estado = 0 if back_button.estado == 1 or back_button.estado == 2 : nexttm = delta next_pic_num -= 2 if next_pic_num < -1: next_pic_num = -1 #nexttm = 0 #force reload back_button.estado = 0 if forward_button.estado == 1 or forward_button.estado == 2 : nexttm = delta forward_button.estado = 0 # All config.BUTTONS go to idle after processing them, regardless of state # WHILE LOOP ends here try: DISPLAY.loop_stop() except Exception as e: print("this was going to fail if previous try failed!") if KEYBOARD: kbd.close() DISPLAY.destroy()
legend = pi3d.TextBlock(-340, (200 - (i * 30)), 0.1, 0.0, 30, data_obj=peripherals.eg_object, text_format=varname + " {:2.1f}", attr=varname, size=0.3, spacing="C", space=1.1, colour=(colors[i][0], colors[i][1], colors[i][2], 1)) text.add_text_block(legend) i += 1 grapharea = pi3d.Sprite(camera=graphics.CAMERA, w=780, h=460, z=3.0, x=0, y=0) grapharea.set_shader(graphics.MATSH) grapharea.set_material((1.0, 1.0, 1.0)) grapharea.set_alpha(0.6) def inloop(textchange=False, activity=False, offset=0): global nextsensorcheck, graph if offset == 0 and not peripherals.check_touch_pressed(): nextsensorcheck = 0 text.regen() i = 0 for varname in showvars: y_vals[i][:-1] = y_vals[i][1:] y_vals[i][-1] = getattr(peripherals.eg_object, varname) i += 1
t.start() while not new_pic: # wait for array to be filled first time time.sleep(0.1) ######################################################################## DISPLAY = pi3d.Display.create(x=mdl_dims, y=mdl_dims, frames_per_second=max_fps) DISPLAY.set_background(0.0, 0.0, 0.0, 0.0) txtshader = pi3d.Shader("uv_flat") font = pi3d.Font("fonts/FreeMono.ttf", font_size=30, color=(0, 255, 0, 255)) # blue green 1.0 alpha CAMERA = pi3d.Camera(is_3d=False) tex = pi3d.Texture(npa) sprite = pi3d.Sprite(w=tex.ix, h=tex.iy, z=1.0) sprite.set_draw_details(txtshader, [tex]) mykeys = pi3d.Keyboard() fps = "00.0 fps" N = 10 fps_txt = pi3d.String(camera=CAMERA, is_3d=False, font=font, string=fps, x=0, y=preview_H / 2 - 10, z=1.0) fps_txt.set_shader(txtshader) i = 0 last_tm = time.time()
def __setup_sprites(self): flat = Shader("uv_flat") matflat = Shader("mat_flat") if is_x11(): # load an image as bg self.bg_img = pi3d.ImageSprite(load_texture( self.__choose_random_bg()), flat, w=1920, h=1080, z=101) else: self.bg_img = None if is_pi(): self.bgr = BGRotater(960, 540, -1, img("bg"), self.bg_change_interval) self.bgr.change() bg = pi3d.Sprite(w=int(self.DISPLAY.width * self.sf), h=int(self.DISPLAY.height * self.sf), z=100) bg.set_shader(matflat) bg.set_alpha(0) self.bg = Flashing(bg) logger.debug("Loading other images") logo_d = (80, 80) self.logo = pi3d.ImageSprite(load_icon( "icons/logo.png", fallback="icons/logo_fallback.png"), flat, w=logo_d[0], h=logo_d[1], x=(1920 - logo_d[0]) / 2 - 40, y=(-1080 + logo_d[1]) / 2 + 40, z=50) self.people = Disappear(pi3d.ImageSprite( load_icon("icons/people.png"), flat, w=logo_d[0], h=logo_d[1], x=(1920 - logo_d[0]) / 2 - 40 - logo_d[0] - 20, y=(-1080 + logo_d[1]) / 2 + 40, z=50), duration=config.md_ev_interval + 1, fade=0.5) in_d = (512 * 0.75, 185 * 0.75) self.instructions = pi3d.ImageSprite( load_icon("icons/instructions.png"), flat, w=in_d[0], h=in_d[1], x=(-1920 + in_d[0]) / 2 + 40, y=(-1080 + in_d[1]) / 2 + 40, z=50) self.instructions = LazyTrigger( Disappear(self.instructions, duration=5)) logger.debug("Loading font") printable_cps = list( itertools.chain( range(ord(' '), ord('~')), range(161, 255), [ord("○"), ord("●"), ord("◌"), ord("◉"), ord('Ω')])) fontfile = img("UbuntuMono-B_circle.ttf") font = OutlineFont(fontfile, font_size=80, image_size=1024, outline_size=2, codepoints=printable_cps, mipmap=False, filter=GL_LINEAR) self.goal_time = ChangingText(flat, font=font, string=self.__get_time_since_last_goal(), is_3d=False, justify='C', x=0, y=-450, z=50) self.game_mode_ui = ChangingText(flat, font=font, string=self.__get_mode_string(None), is_3d=False, justify='R', x=920, y=480, z=50) self.feedback = KeysFeedback(flat) s = 512 self.yCounter = Move( Counter(0, flat, config.team_colors['yellow'], w=s, h=s, z=50)) self.bCounter = Move( Counter(0, flat, config.team_colors['black'], w=s, h=s, z=50)) playerfont = OutlineFont(fontfile, font_size=50, image_size=768, outline_size=2, codepoints=printable_cps, mipmap=False, filter=GL_LINEAR) self.yPlayers = Multiline(flat, font=playerfont, string=self.getPlayers(left=True), x=-380, y=-250, z=50, justify='C') self.bPlayers = Multiline(flat, font=playerfont, string=self.getPlayers(left=False), x=380, y=-250, z=50, justify='C') menufont = OutlineFont(fontfile, (255, 255, 255, 255), font_size=50, image_size=768, codepoints=printable_cps, mipmap=False, filter=GL_LINEAR) arrow = load_icon("icons/arrow.png") menu = Menu(menufont, arrow, wchar=60, n=12, z=10) self.menu = MenuTree(self.main_menu, menu, rootTitle="Game mode") self.ledShapes = { "YD": FlatDisk(radius=20, sides=12, x=-100, y=-430, z=0, rx=90), "YI": FlatDisk(radius=20, sides=12, x=-100, y=-370, z=0, rx=90), "OK": FlatDisk(radius=50, sides=12, x=0, y=-400, z=0, rx=90), "BD": FlatDisk(radius=20, sides=12, x=100, y=-430, z=0, rx=90), "BI": FlatDisk(radius=20, sides=12, x=100, y=-370, z=0, rx=90), } red = (1, 0, 0, 0) green = (0, 1, 0, 0) self.blackColor = (0, 0, 0, 0) self.ledColors = { "YD": red, "YI": green, "OK": green, "BD": red, "BI": green } self.leds = [] self.winner = WinnerString(flat) # move immediately to position self.__move_sprites()
-100, 0.1, 0.0, 15, data_obj=peripherals.eg_object, attr="act_temp", text_format=unichr(0xE021) + u" {:2.1f}°C", size=0.2, spacing="F", space=0.02, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(temp_block) officearea = pi3d.Sprite(camera=graphics.CAMERA, w=380, h=220, z=3, x=-70, y=110) officearea.set_shader(graphics.MATSH) officearea.set_material((1.0, 0.0, 0.0)) kitchenarea = pi3d.Sprite(camera=graphics.CAMERA, w=220, h=200, z=3, x=-140, y=-110) kitchenarea.set_shader(graphics.MATSH) kitchenarea.set_material((0.0, 1.0, 0.0)) storagearea = pi3d.Sprite(camera=graphics.CAMERA,
0.0, 40, text_format=subtext + actualword, size=size, spacing="F", space=0.02, colour=(1, 1, 1, 1)) text6.add_text_block(event) actualy -= event.size * graphics.pointFont.height actualy -= 20 count += 1 else: break background2 = pi3d.Sprite(camera=graphics.CAMERA, w=780, h=460, z=2, x=0, y=0) background2.set_shader(graphics.MATSH) background2.set_material((0.0, 0.0, 0.0)) background2.set_alpha(0.6) upperboarder = pi3d.Sprite(camera=graphics.CAMERA, w=780, h=20, z=0.1, x=0, y=240) upperboarder.set_shader(graphics.MATSH) upperboarder.set_material((0.0, 0.0, 0.0)) upperboarder.set_alpha(0.0) lowerboarder = pi3d.Sprite(camera=graphics.CAMERA, w=780, h=20,
t = threading.Thread(target=get_pics) # set up and start capture thread t.daemon = True t.start() while not new_pic: # wait for array to be filled first time time.sleep(0.1) ######################################################################## DISPLAY = pi3d.Display.create(x=150, y=150, frames_per_second=30) shader = pi3d.Shader("shaders/night_vision") CAMERA = pi3d.Camera(is_3d=False) tex = pi3d.Texture(npa) rim = pi3d.Texture('textures/snipermode.png') noise = pi3d.Texture('textures/Roof.png') sprite = pi3d.Sprite(w=DISPLAY.height * tex.ix / tex.iy, h=DISPLAY.height, z=5.0) sprite.set_draw_details(shader, [tex, rim, noise]) mykeys = pi3d.Keyboard() lum_threshold = 0.2 lum_amplification = 4.0 while DISPLAY.loop_running(): if new_pic: tex.update_ndarray(npa) new_pic = False sprite.set_custom_data(48, [time.time(), lum_threshold, lum_amplification]) sprite.draw()