I have a script written up that takes an image and displays it. I originally intended to have the image then have parts fall away, but I am having trouble getting parts of the image to move separate. Is there a simple way to do this or am I going to have to apply some cleverness? thanks in advance.

Recommended Answers

All 10 Replies

First of all I would personally use pygame for that and livewires(just because) and I would think you'd need to have those parts of the image as separate images, place them on the frame so that they appear to be one image, then you could manipulate them as sprites individually.

I second Pygame, but I would use PIL for the image processing. You can cut up the image, splice, convert to greyscale and much more.

never used PIL, but sounds legit. There you go @Thropian, get back to us with how it turns out.

Here is an example I have done for how PIL can be used. Also, it demonstrates how awesome python is =)

So I looked at your code tech-b didn't see PIL mentioned in the code. probably just missed it. But that seems like an interesting idea but, if you turn wouldn't the screen turn entirely red? So that would only work while you were standing still?

But back to this I was working on getting some stuff together.

from Tkinter import *
from PIL import Image
import ImageTk,sys,random,ImageGrab

#gets the screenshot
img=ImageGrab.grab()
img.save(sys.path[0] + "\screenshot.bmp")

def Pixel(photo,x,y):#pick out a 5x5 box of pixels
    Xstart = random.randint(0,x-5)
    Ystart = random.randint(0,y-5)
    for Ypoint in range(Ystart,Ystart+5):
        for Xpoint in range(Xstart,Xstart+5):
            print photo.getdata()[(x*(Ypoint-1))+Xpoint],
        print

class App:

    def __init__(self, master):

        frame = Frame(master)
        frame.pack()

        canvas = Canvas(frame, width = root.winfo_screenwidth(), height = root.winfo_screenheight(), bg = "blue")
        canvas.pack()

        photo = Image.open("%s\screenshot.bmp"%sys.path[0])
        print photo
        x,y = photo.size
        print x,y
        tkpi = ImageTk.PhotoImage(photo)
        canvas.create_image(0,0,image=tkpi, anchor = NW)#display the screenshot
        canvas.image = tkpi#not really useful yet but it is here
        Pixel(photo,x,y)

root = Tk()

d = App(root)

w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)#makes it full screen
root.focus_set()
root.geometry("%dx%d+0+0" % (w, h))
root.wait_window()

Thats the code so far. That could probably use a lot of cleaning up. But I started looking into making a square and drawing the pixels on it to make the image, and then just making a second black square to put in it's place as I moved the colored square around. Since there was no "easy way" I was applying cleverness. Right now I'm trying to make pixels (really just small rectangles) and color them from the color code found in the Pixel command

In my code you can see "import Image", you don't necessarily need "from PIL import Image".

And you are correct about the the red taking over if I wear the cam on myself. I plan on adapting that code for a stationary gun turret in my yard. With the wearing the cam, I plan on implementing OpenCV with HarrCascades and what not.

Anyway back to the subject at hand. I see you are using PIL, so try cropping the image and moving the crops down the image with an overlay of the image as the base. What ever you crop you can make either transparent or blue or whatever you want.

As for the cleanup, you are doing very good, looks better than a lot of my code. The only thing I could suggest would be comment more.

commented: Pointed me in the right direction. +3

ok well I got it to work. It was intended as a screen saver but there are a few things I'd need to tackle before that would work.

from Tkinter import *
from PIL import Image
import ImageTk,sys,random,ImageGrab

img=ImageGrab.grab()#get a screenshot
img.save("screenshot.bmp")

allowed = {}

def Pixel(photo,x,y):#pick out a 50x50 box of pixels
    Xstart,Ystart = random.choice(allowed["locations"])
    allowed["locations"].remove((Xstart,Ystart))
    Xstart,Ystart = Xstart*50,Ystart*50
    return Xstart,Ystart

def Start(canvas,frame):#runs the whole program
    photo = Image.open("screenshot.bmp")
    X,Y = photo.size
    Xstart,Ystart = Pixel(photo,X,Y)
    NewBlock = photo.crop([Xstart,Ystart,Xstart+50,Ystart+50])
    canvas.create_rectangle(Xstart,Ystart, Xstart+49,Ystart+49, fill="black")
    tkpi2 = ImageTk.PhotoImage(NewBlock)
    canvas.create_image(Xstart, Ystart, image=tkpi2, anchor=NW)
    canvas.image.append(tkpi2)
    canvas.after(1000,lambda:Fall(canvas,canvas.find_all()[-1],Y,frame))
    if allowed["locations"] == []:
        canvas = reset(frame)
        
def Fall(canvas,item,Y,frame):#makes a piece fall
    canvas.move(item,0,2)
    if canvas.coords(item)[1] < Y:
        canvas.after(10,lambda:Fall(canvas,item,Y,frame))
    else:
        canvas.delete(item)
        Start(canvas,frame)

def reset(frame):
    canvas = Canvas(frame, width = root.winfo_screenwidth(), height = root.winfo_screenheight(), bg = "blue")
    canvas.pack()

    photo = Image.open("screenshot.bmp")
    X,Y = photo.size
    tkpi = ImageTk.PhotoImage(photo)
    canvas.create_image(0,0,image=tkpi, anchor = NW)#display the screenshot
    canvas.image = []
    canvas.image.append(tkpi)#makes the screen stay
    allowed["locations"] = []
    for x in range(0,(X-50)/50+1):
        for y in range(0,(Y-50)/50+1):
            allowed["locations"].append((x,y))
    return canvas

class App:

    def __init__(self, master):

        frame = Frame(master)
        frame.pack()

        canvas = reset(frame)

        Start(canvas,frame)

            
root = Tk()

d = App(root)

w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)#makes it full screen
root.focus_set()
root.geometry("%dx%d+0+0" % (w, h))
root.wait_window()

(73 lines of code oh no)

When I converted it to an exe with py2exe and then changed exe to scr (read that somewhere, a how to screen saver thing) but when it runs it brings up a black box before it takes the screen shot. also it doesn't close on mouse move so you have to actually alt-f4 out of it. and the mouse sits on top of the window created.

For the terminal to not pop up use:

setup(
        windows=['trypyglet.py'],
        ...

Instead of:

setup(
        scripts=['trypyglet.py'],
        ...

For it to exit, you could use sys.exit() if the mouse moves. I believe you can poll Tk for the mouse events, if not, you can use ctypes to grab the mouse data from windll if your on Windows. Not sure of the Linux equivalent for mouse events (I think its xorLib).

ok in the setup file I ended up needing

setup(scripts=['screen saver.pyw'],
      windows=['screen saver.pyw'])

With just scripts it wouldn't run. Also I was able to find out if the mouse moved by binding

master.bind("<Motion>",lambda:root.destroy())

now to hide the mouse and bind to all keyboard inputs (hopefully a short code) and the mouse buttons.

Alright the program is now finished

to hide the mouse I changed line 38 to:

canvas = Canvas(frame, width = root.winfo_screenwidth(), height = root.winfo_screenheight(), bg = "blue", cursor="none")

so the cursor is now invisible
and I bound

master.bind("<Motion>",lambda:root.destroy())
        master.bind("<Key>",lambda:root.destroy())
        master.bind("<Button-1>",lambda:root.destroy())
        master.bind("<Button-2>",lambda:root.destroy())
        master.bind("<Button-3>",lambda:root.destroy())

to make the computer wake up
then packed it with py2exe

Tech-B for all your help I'm mentioning you in the special thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.