I wanted to turn my raspberry pi into a slideshow device but I barely know python 3 could anyone help me fix this code I found online? It's supposed to display the images in the list I created but it doesn't run. The only changes I made to this code was the creation of the list so I have no idea why it does not work. The error I'm getting is
Traceback (most recent call last):
File "bro.py", line 82, in <module>
slideshow.start()
File "bro.py", line 56, in start
self.main()
File "bro.py", line 48, in main
self.set_image()
File "bro.py", line 42, in set_image
self.image_name = next(self.images)
StopIteration
Here is the code:
#!/usr/bin/env python3
"""Display a slideshow from a list of filenames"""
import os
import tkinter
from itertools import cycle
from PIL import Image, ImageTk
class Slideshow(tkinter.Tk):
"""Display a slideshow from a list of filenames"""
def __init__(self, images, slide_interval):
"""Initialize
images = a list of filename
slide_interval = milliseconds to display image
"""
tkinter.Tk.__init__(self)
self.geometry("+0+0")
self.slide_interval = slide_interval
self.images = images
self.set_images(images)
self.slide = tkinter.Label(self)
self.slide.pack()
def set_images(self, images):
self.images = cycle(images)
def center(self):
"""Center the slide window on the screen"""
self.update_idletasks()
w = self.winfo_screenwidth()
h = self.winfo_screenheight()
size = tuple(int(_) for _ in self.geometry().split('+')[0].split('x'))
x = w / 2 - size[0] / 2
y = h / 2 - size[1] / 2
self.geometry("+%d+%d" % (x, y))
def set_image(self):
"""Setup image to be displayed"""
self.image_name = next(self.images)
filename, ext = os.path.splitext(self.image_name)
self.image = ImageTk.PhotoImage(Image.open(self.image_name))
def main(self):
"""Display the images"""
self.set_image()
self.slide.config(image=self.image)
self.title(self.image_name)
self.center()
self.after(self.slide_interval, self.start)
def start(self):
"""Start method"""
self.main()
self.mainloop()
if __name__ == "__main__":
slide_interval = 2500
# use a list
images = [
"/~/definitely/1550099164562.png",
"/~/definitely/1550770995551.png",
"/~/definitely/1550771217013.png",
"/~/definitely/1550771726391.jpg"]
# all the specified file types in a directory
# "." us the directory the script is in.
# exts is the file extentions to use. it can be any extention that pillow supports
# http://pillow.readthedocs.io/en/3.3.x/handbook/image-file-formats.html
import glob
images = glob.glob("*.jpg")
path = "."
exts = ["jpg", "bmp", "png", "gif", "jpeg"]
images = [fn for fn in os.listdir(path) if any(fn.endswith(ext) for ext in exts)]
# start the slideshow
slideshow = Slideshow(images, slide_interval)
slideshow.start()
Try next(iter(images)) instead of next(images).
BTW, I have Raspberry Pi slideshows for both Tkinter and Kivy on my tachyonlabs GitHub ... they also download photos from Instagram, but if you don't hook that up or there's no Internet connection they will just cycle through the images in the image directory you specify, with your chosen order and duration.
Related
I am developing a multi-platform application that manipulates VLC through python-vlc and makes it draw in a Tkinter window.
I am using the following simplified code (inspired from the tkvlc.py example from python-vlc):
import os
import platform
import sys
import tkinter
from ctypes import c_void_p, cdll
from threading import Thread
import vlc
system = platform.system()
if system == "Darwin":
# find the accurate Tk lib for Mac
libtk = "libtk%s.dylib" % (tkinter.TkVersion,)
if "TK_LIBRARY_PATH" in os.environ:
libtk = os.path.join(os.environ["TK_LIBRARY_PATH"], libtk)
else:
prefix = getattr(sys, "base_prefix", sys.prefix)
libtk = os.path.join(prefix, "lib", libtk)
dylib = cdll.LoadLibrary(libtk)
_GetNSView = dylib.TkMacOSXGetRootControl
_GetNSView.restype = c_void_p
_GetNSView.argtypes = (c_void_p,)
del dylib
class Window(tkinter.Tk):
def register(self, player):
id = self.winfo_id()
print(id)
if system == "Darwin":
player.set_nsobject(_GetNSView(id))
elif system == "Linux":
player.set_xwindow(id)
elif system == "Windows":
player.set_hwnd(id)
def play(instance, player, path):
media = instance.media_new_path(path)
player.set_media(media)
player.play()
if __name__ == "__main__":
instance = vlc.Instance()
player = instance.media_player_new()
window = Window()
window.register(player)
thread = Thread(target=play, args=(instance, player, sys.argv[1]))
thread.start()
window.mainloop()
On MacOS, the size of the video is not adapted to the size of the window.
If the video is to large for the window, it is cropped, if it is too small, it stands in the left bottom corner and is surrounded by black.
The size of the video is updated only when the window is resized.
Here is a video capture of the problem.
This does not occur on Linux or on Window.
The same problem occurs with the tkvlc.py example from python-vlc) if the call to the OnResize method is blocked line 471 (the method resizes the window to have the size ratio of the video).
What should I do to force VLC to resize the video to fit the window automatically, as it does by default on other OSes?
I have fixed that error by understanding the code in tkvlc.py code in the examples https://github.com/oaubert/python-vlc/blob/master/examples/tkvlc.py
The function that resizes the video in mac os if it's wrong is this one in tkvlc.py:
def _wiggle(self, d=4):
# wiggle the video to fill the window on macOS
if not self._isFull:
v = self.videoPanel
g, w, h, x, y = _geometry5(v)
w = int(w) + d
# x = int(x) - d
# h = int(h) + d
if _geometry(v, w, h, x, y) != g:
self.after_idle(_geometry, v, g)
if d > 1: # repeat a few times
self.after(100, self._wiggle, d - 1)
i was trying to make the user input file audio in wav or mp3 format to low pass filter it
i am supposed to use tkinter to create GUI so that use can use two buttons one to input file and other to call function runlow which is the filter i dont know where i went wrong
i don't know why i need to add details to the question though stackflow ?
but i got this error :
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\ezz\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "C:\Users\ezz\desktop\voicerecorder.py", line 173, in runlow
filtered = running_mean(channels[0], N).astype(channels.dtype)
TypeError: 'NoneType' object is not subscriptable
here is the main code
from cProfile import label
from doctest import master
from importlib.metadata import files
from pydoc import text
from tkinter import *
from tkinter import filedialog
import matplotlib.pyplot as plt
from functools import partial
import numpy as np
from tkinter.filedialog import asksaveasfile
from tkinter import ttk
import wave
import math
import contextlib
import warnings
outname = (r"filtered.wav")
def fileaudio():
global fname1
fname1 = filedialog.askopenfilename(filetypes=(("Audio files", "*.wav;*.mp3"),
("All files", "*.*") ))
print(fname1)
return fname1
warnings.simplefilter("ignore", DeprecationWarning)
# Change label contents
root =Tk()
root.geometry("1280x800")
root.resizable(False,False)
root.title("Audio filter")
root.configure(background="white")
#icon
image_icon=PhotoImage(file="filter.png")
root.iconphoto(False,image_icon)
#logo
photo=PhotoImage(file="filter.png")
myimage=Label(image=photo,background="white")
myimage.pack(padx=5,pady=5)
#name
Label(text="Audio filter",font="ariel 30 bold",background="black",fg="white").pack()
#entry box
def runlow():
cutOffFrequency = 400.0
# from http://stackoverflow.com/questions/13728392/moving-average-or-running-mean
def running_mean(x, windowSize):
cumsum = np.cumsum(np.insert(x, 0, 0))
return (cumsum[windowSize:] - cumsum[:-windowSize]) / windowSize
# from http://stackoverflow.com/questions/2226853/interpreting-wav-data/2227174#2227174
def interpret_wav(raw_bytes, n_frames, n_channels, sample_width, interleaved = True):
if sample_width == 1:
dtype = np.uint8 # unsigned char
elif sample_width == 2:
dtype = np.int16 # signed 2-byte short
else:
raise ValueError("Only supports 8 and 16 bit audio formats.")
channels = np.fromstring(raw_bytes, dtype=dtype)
if interleaved:
# channels are interleaved, i.e. sample N of channel M follows sample N of channel M-1 in raw data
channels.shape = (n_frames, n_channels)
channels = channels.T
else:
# channels are not interleaved. All samples from channel M occur before all samples from channel M-1
channels.shape = (n_channels, n_frames)
return channels
with contextlib.closing(wave.open(fname1,'rb')) as spf:
sampleRate = spf.getframerate()
ampWidth = spf.getsampwidth()
nChannels = spf.getnchannels()
nFrames = spf.getnframes()
# Extract Raw Audio from multi-channel Wav File
signal = spf.readframes(nFrames*nChannels)
spf.close()
channels = interpret_wav(signal, nFrames, nChannels, ampWidth, True)
# get window size
# from http://dsp.stackexchange.com/questions/9966/what-is-the-cut-off-frequency-of-a-moving-average-filter
freqRatio = (cutOffFrequency/sampleRate)
N = int(math.sqrt(0.196196 + freqRatio**2)/freqRatio)
# Use moviung average (only on first channel)
filtered = running_mean(channels[0], N).astype(channels.dtype)
wav_file = wave.open(outname, "w")
wav_file.setparams((1, ampWidth, sampleRate, nFrames, spf.getcomptype(), spf.getcompname()))
wav_file.writeframes(filtered.tobytes('C'))
wav_file.close()
#button
record=Button(root,font="ariel 20",text="Input",bg="black",fg="white",border=0,command=fileaudio).pack(pady=30)
record2=Button(root,font="ariel 20",text="Filter",bg="black",fg="white",border=0,command=runlow).pack(pady=30)
#functions to integrate
# from http://stackoverflow.com/questions/13728392/moving-average-or-running-mean
root.mainloop()
You forgot to return the filename from your input() function.
def input():
fname = filedialog.askopenfilename(filetypes=(("Audio files", "*.wav;*.mp3"),
("All files", "*.*") ))
print(fname)
return fname # <== you dropped this
fname = input()
Also there's another error, you must use askinputfilename, not askinputfile.
FWIW you should not use the name input() for your function since it overwrites and disables python's built-in input function.
I'm working on a Python script to monitor a folder to check whether a new *.JPG file is added to that folder and then do some tasks. The code is working, but after some time after being started, it seems to be freezing and stops working even a new file is added to the folder.
Here is the code:
# -*- encoding: iso-8859-1 -*-
import time
import os
import flickrapi
import shutil
from PIL import Image
from PIL.ExifTags import TAGS
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
if __name__ == "__main__":
patterns = ["*.jpg"]
ignore_patterns = None
ignore_directories = False
case_sensitive = False
my_event_handler = PatternMatchingEventHandler(patterns, ignore_patterns, ignore_directories, case_sensitive)
def get_exif(img):
''' Extract Exif data from image '''
def copyright(img):
# get the path of img and create an output filename
tail = os.path.split(img)[1]
filename = 'wtmk_' + tail[:-3] + 'png'
#open the base image and get it's dimensions
while True:
try:
# read file
base_image = Image.open(img)
bw, bh = base_image.size
bw2 = bw // 2
break
except IOError:
time.sleep(5)
''' Add watermark to image '''
return waterMarkedImage
def on_created(event):
# Add the watermark
file = copyright(event.src_path)
# extract EXIF data
exifdata = get_exif(event.src_path)
''' Send the image to FLICKR '''
# Create and start the observer
my_event_handler.on_created = on_created
path = "c:\\temp"
go_recursively = False
my_observer = Observer()
my_observer.schedule(my_event_handler, path, recursive=go_recursively)
my_observer.start()
try:
while True:
time.sleep(5)
except KeyboardInterrupt:
my_observer.stop()
my_observer.join()
I'm running the above code using Python 3.8 on a Windows 10 machine. Any help would be awesome!
Marcio
It's probably an issue with your cmd.exe
To fix the script freezing open your cmd, click on your cmd icon in the top left, then go to Defaults and uncheck the QuickEdit Mode.
Then restart cmd and start your script. Hope that helps!
I am currently trying to make life easier by having the code pull all the frames into my code and execute the animation. My current code is:
import time
from tkinter import *
import os
root = Tk()
imagelist = []
for file in os.listdir("MY-DIRECTORY"):
if file.endswith(".gif"):
imagelist.append(PhotoImage(file=str(os.path.join("MY-DIRECTORY", file))))
# extract width and height info
photo = PhotoImage(file=imagelist[0])
width = photo.width()
height = photo.height()
canvas = Canvas(width=width, height=height)
canvas.pack()
# create a list of image objects
giflist = []
for imagefile in imagelist:
photo = PhotoImage(file=imagefile)
giflist.append(photo)
# loop through the gif image objects for a while
for k in range(0, 1000):
for gif in giflist:
canvas.create_image(width / 2.0, height / 2.0, image=gif)
canvas.update()
time.sleep(0.1)
root.mainloop()
When I try to execute the file it gives me this error which I cannot make sense of.
Traceback (most recent call last):
File "C:/Users/Profile/Desktop/folder (2.22.2019)/animation2.py", line 21, in <module>
photo = PhotoImage(file=imagelist[0])
File "C:\Users\Profile\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 3545, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
File "C:\Users\Profile\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 3501, in __init__
self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: couldn't open "pyimage1": no such file or directory
Note: I am adapting this code to fit my needs I did not write it.
I ran some print statements to verify the pyimage was being uploaded to the array but I cannot figure out why its saying there is no such file or directory if its already uploaded to the array. Can you all please shine some light.
I found that I was creating an unnecessary array of objects lower in the code. giflist[]. I ultimately resolved the issue by removing it and having the loop use the array that was created earlier in the code imagelist. The following code works now.
import time
from tkinter import *
import os
root = Tk()
imagelist = []
for file in os.listdir("My-Directory"):
if file.endswith(".gif"):
imagelist.append(PhotoImage(file=str(os.path.join("My-Directory", file))))
# Extract width and height info
photo = PhotoImage(file="My-Directory")
width = photo.width()
height = photo.height()
canvas = Canvas(width=width, height=height)
canvas.pack()
# Loop through the gif image objects for a while
for k in range(0, len(imagelist)):
for gif in imagelist:
canvas.create_image(width / 2.0, height / 2.0, image=gif)
canvas.update()
time.sleep(0.1)
root.mainloop()
Traceback (most recent call last):
File "test.py", line 10, in <module>
tracker = cv2.Tracker_create("MIL")
AttributeError: module 'cv2.cv2' has no attribute 'Tracker_create
I get the above error when I try to run:
import cv2
import sys
if __name__ == '__main__' :
# Set up tracker.
# Instead of MIL, you can also use
# BOOSTING, KCF, TLD, MEDIANFLOW or GOTURN
tracker = cv2.Tracker_create("MIL")
# Read video
video = cv2.VideoCapture(0)
# Exit if video not opened.
if not video.isOpened():
print ("Could not open video")
sys.exit()
# Read first frame.
ok, frame = video.read()
if not ok:
print ('Cannot read video file')
sys.exit()
# Define an initial bounding box
bbox = (287, 23, 86, 320)
# Uncomment the line below to select a different bounding box
# bbox = cv2.selectROI(frame, False)
# Initialize tracker with first frame and bounding box
ok = tracker.init(frame, bbox)
while True:
# Read a new frame
ok, frame = video.read()
if not ok:
break
# Update tracker
ok, bbox = tracker.update(frame)
# Draw bounding box
if ok:
p1 = (int(bbox[0]), int(bbox[1]))
p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
cv2.rectangle(frame, p1, p2, (0,0,255))
# Display result
cv2.imshow("Tracking", frame)
# Exit if ESC pressed
k = cv2.waitKey(1) & 0xff
if k == 27 : break
I found an answer here: How to add "Tracker" in openCV python 2.7
But this confused me more. I'm on MacOSX and I'm just getting started with OpenCV and I'm not really sure how to recompile OpenCV with the correct modules.
Thanks in advance, and sorry if I'm missing something obvious.
So it wasn't a case of the installation, but the constructor name had changed.
tracker = cv2.Tracker_create("MIL")
Should be:
tracker = cv2.TrackerMIL_create()