change a label transparency to 0 in python (pygtk) - python

i want to add a transparent label over an image using pygtk, it does not seem to work with me, the label over comes the background pictures (slider) and i can only see my label. i had the idea to make a label transparent in order to see the background picture,, any suggestions please?
#!/usr/bin/python
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
from time import sleep
import urllib2
import os
import xml.dom
import xml.dom.minidom
import pygtk
pygtk.require('2.0')
import gtk
import glib
#Configure the inputs/outputs
GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.IN, pull_up_down = GPIO.PUD_UP) # The emplyee button
xmldoc = xml.dom.minidom.parse('/var/www/delay.xml')
delay = xmldoc.getElementsByTagName('delay')
def _begin():
if (GPIO.input(4)==0):
response=urllib2.urlopen("http://localhost/num.php?id_service=1",timeout=5) **#retrieve the next ticket number from MYSQL DB through an url**
number = response.read()
label = gtk.Label("9999 ") # for testing else it would be label= gtk.Label(number)**
response.close()
sleep(1);
return _begin()
def is_image(filename):
""" File is image if it has a common suffix and it is a regular file """
if not os.path.isfile(filename):
return False
for suffix in ['.jpg', '.png', '.bmp']:
if filename.lower().endswith(suffix):
return True
return False
def resizeToFit(image, frame, aspect=True, enlarge=False):
"""Resizes a rectangle to fit within another.
Parameters:
image -- A tuple of the original dimensions (width, height).
frame -- A tuple of the target dimensions (width, height).
aspect -- Maintain aspect ratio?
enlarge -- Allow image to be scaled up?
"""
if aspect:
return scaleToFit(image, frame, enlarge)
else:
return stretchToFit(image, frame, enlarge)
def scaleToFit(image, frame, enlarge=False):
image_width, image_height = image
frame_width, frame_height = frame
image_aspect = float(image_width) / image_height
frame_aspect = float(frame_width) / frame_height
# Determine maximum width/height (prevent up-scaling).
if not enlarge:
max_width = min(frame_width, image_width)
max_height = min(frame_height, image_height)
else:
max_width = frame_width
max_height = frame_height
# Frame is wider than image.
if frame_aspect > image_aspect:
height = max_height
width = int(height * image_aspect)
# Frame is taller than image.
else:
width = max_width
height = int(width / image_aspect)
return (width, height)
def stretchToFit(image, frame, enlarge=False):
image_width, image_height = image
frame_width, frame_height = frame
# Stop image from being blown up.
if not enlarge:
width = min(frame_width, image_width)
height = min(frame_height, image_height)
else:
width = frame_width
height = frame_height
return (width, height)
class ResizableImage(gtk.DrawingArea):
def __init__(self, aspect=True, enlarge=False,
interp=gtk.gdk.INTERP_NEAREST, backcolor=None, max=(1600,1200)):
"""Construct a ResizableImage control.
Parameters:
aspect -- Maintain aspect ratio?
enlarge -- Allow image to be scaled up?
interp -- Method of interpolation to be used.
backcolor -- Tuple (R, G, B) with values ranging from 0 to 1,
or None for transparent.
max -- Max dimensions for internal image (width, height).
"""
super(ResizableImage, self).__init__()
self.pixbuf = None
self.aspect = aspect
self.enlarge = enlarge
self.interp = interp
self.backcolor = backcolor
self.max = max
self.connect('expose_event', self.expose)
self.connect('realize', self.on_realize)
def on_realize(self, widget):
if self.backcolor is None:
color = gtk.gdk.Color()
else:
color = gtk.gdk.Color(*self.backcolor)
self.window.set_background(color)
def expose(self, widget, event):
# Load Cairo drawing context.
self.context = self.window.cairo_create()
# Set a clip region.
self.context.rectangle(
event.area.x, event.area.y,
event.area.width, event.area.height)
self.context.clip()
# Render image.
self.draw(self.context)
return False
def draw(self, context):
# Get dimensions.
rect = self.get_allocation()
x, y = rect.x, rect.y
# Remove parent offset, if any.
parent = self.get_parent()
if parent:
offset = parent.get_allocation()
x -= offset.x
y -= offset.y
# Fill background color.
if self.backcolor:
context.rectangle(x, y, rect.width, rect.height)
context.set_source_rgb(*self.backcolor)
context.fill_preserve()
# Check if there is an image.
if not self.pixbuf:
return
width, height = resizeToFit(
(self.pixbuf.get_width(), self.pixbuf.get_height()),
(rect.width, rect.height),
self.aspect,
self.enlarge)
x = x + (rect.width - width) / 2
y = y + (rect.height - height) / 2
context.set_source_pixbuf(
self.pixbuf.scale_simple(width, height, self.interp), x, y)
context.paint()
def set_from_pixbuf(self, pixbuf):
width, height = pixbuf.get_width(), pixbuf.get_height()
# Limit size of internal pixbuf to increase speed.
if not self.max or (width < self.max[0] and height < self.max[1]):
self.pixbuf = pixbuf
else:
width, height = resizeToFit((width, height), self.max)
self.pixbuf = pixbuf.scale_simple(
width, height,
gtk.gdk.INTERP_BILINEAR)
self.invalidate()
def set_from_file(self, filename):
self.set_from_pixbuf(gtk.gdk.pixbuf_new_from_file(filename))
def invalidate(self):
self.queue_draw()
class DemoGtk:
SECONDS_BETWEEN_PICTURES = int(delay[0].firstChild.nodeValue)
FULLSCREEN = True
WALK_INSTEAD_LISTDIR = True
def __init__(self):
self.window = gtk.Window()
self.window.connect('destroy', gtk.main_quit)
self.window.set_title('Slideshow')
self.image = ResizableImage( True, True, gtk.gdk.INTERP_BILINEAR)
self.image.show()
self.window.add(self.image)
self.window.add(label) # GO to def _begin there i declared the label with its value**
self.load_file_list()
self.window.show_all()
if self.FULLSCREEN:
self.window.fullscreen()
glib.timeout_add_seconds(self.SECONDS_BETWEEN_PICTURES, self.on_tick)
self.display()
def load_file_list(self):
""" Find all images """
self.files = []
self.index = 0
if self.WALK_INSTEAD_LISTDIR:
for directory, sub_directories, files in os.walk('.'):
for filename in files:
if is_image(filename):
filepath = os.path.join(directory, filename)
self.files.append(filepath)
else:
for filename in os.listdir('.'):
if is_image(filename):
self.files.append(filename)
print "Images:", self.files
def display(self):
""" Sent a request to change picture if it is possible """
if 0 <= self.index < len(self.files):
self.image.set_from_file(self.files[self.index])
return True
else:
return False
def on_tick(self):
""" Skip to another picture.
If this picture is last, go to the first one. """
self.index += 1
if self.index >= len(self.files):
self.index = 0
return self.display()
if __name__ == "__main__":
while 1:
gui = DemoGtk()
gtk.main()
_begin()
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4

Related

How can I display an image slideshow in tkinter that I made with OpenCv so that I still have 1 line or 3 grids for text?

I'm very new to programming pytho my 3rd month. I'm making a desktop program that is supposed to show appointments and sayings. I already have a function process that opens a window in full screen and displays the slide show.
But I want to place the slide show in a tkinter window so that I can add other labels next to the show.
this is my code i want to call the function in a tkinter window so that i can assign it to a button.
import cv2
import numpy as np
import glob
import os
import random
class Image:
def __init__(self, filename, time=200, size=800):
self.size = size
self.time = time
self.shifted = 1.0
self.img = cv2.imread(filename)
self.height, self.width, _ = self.img.shape
if self.width < self.height:
self.height = int(self.height*size/self.width)
self.width = size
self.img = cv2.resize(self.img, (self.width, self.height))
self.shift = self.height - size
self.shift_height = True
else:
self.width = int(self.width*size/self.height)
self.height = size
self.shift = self.width - size
self.img = cv2.resize(self.img, (self.width, self.height))
self.shift_height = False
self.delta_shift = self.shift/self.time
def reset(self):
if random.randint(0, 1) == 0:
self.shifted = 0.0
self.delta_shift = abs(self.delta_shift)
else:
self.shifted = self.shift
self.delta_shift = -abs(self.delta_shift)
def get_frame(self):
if self.shift_height:
roi = self.img[int(self.shifted):int(self.shifted) + self.size, :, :]
else:
roi = self.img[:, int(self.shifted):int(self.shifted) + self.size, :]
self.shifted += self.delta_shift
if self.shifted > self.shift:
self.shifted = self.shift
if self.shifted < 0:
self.shifted = 0
return roi
def process():
text = f'xXxxxxxXXXXXxxxxxXx'
coordinates = (650, 1100)
font = cv2.FONT_HERSHEY_SIMPLEX
fontScale = 2
color = (255, 0, 255)
thickness = 3
filenames = glob.glob(os.path.join(path, "*"))
cnt = 0
images = []
for filename in filenames:
img = Image(filename)
images.append(img)
if cnt > len(images):
break
cnt += 1
prev_image = images[random.randrange(0, len(images))]
prev_image.reset()
while True:
while True:
img = images[random.randrange(0, len(images))]
if img != prev_image:
break
img.reset()
for i in range(100):
alpha = i/100
beta = 1.0 - alpha
dst = cv2.addWeighted(img.get_frame(), alpha, prev_image.get_frame(), beta, 0.0)
dst = cv2.putText(dst, text, coordinates, font, fontScale, color, thickness,cv2.LINE_AA)
cv2.imshow('Slideshow', dst)
if cv2.waitKey(10) == ord('q'):
cv2.destroyWindow('Slideshow')
return
prev_image = img
for _ in range(100):
cv2.imshow('Slideshow', img.get_frame())
if cv2.waitKey(10) == ord('q'):
cv2.destroyWindow('Slideshow')
return
def start():
cnt = 0
images = []
path = 'pictures'
filenames = glob.glob(os.path.join(path, "*"))
showWindow = tk.Tk()
showWindow.attributes('-fullscreen', True)
showWindow.mainloop()
I tried to display the text in opencv in the pictures but I had problems keeping the text in the exercises. That's why I want to display the whole thing in a Tkinter window so I can do the classification with grid. because I don't just want to display a single image but a slide show
Does the method not work here(**) or I just don't understand it could someone help me.
(**)=
#Import the tkinter library
from tkinter import *
import numpy as np
import cv2
from PIL import Image, ImageTk
#Create an instance of tkinter frame
show_Winow = Tk()
win.geometry("700x550")
#Load the image
img = cv2.imread('tutorialspoint.png')
#Rearrange colors
blue,green,red = cv2.split(img)
img = cv2.merge((red,green,blue))
im = Image.fromarray(img)
imgtk = ImageTk.PhotoImage(image=im)
#Create a Label to display the image
Label(show_Window, image= imgtk).pack()
show_Window.mainloop()

When opening image with PILLOW the image is modified

When opening the postscript image with online tools all the pixels align correctly but when using pillow, the pixels are in different sizes.
[Image of the problem]
[Image of the desired result]
def saveFile(canvas:tk.Canvas):
EpsImagePlugin.gs_windows_binary = r'C:\Program Files\gs\gs9.56.1\bin\gswin64c'
file_name = "img"
canvas.postscript(file=f"images\ps\{file_name}.ps", colormode='color')
psimage=Image.open(f'images\ps\{file_name}.ps')
psimage.save(f'images\png\{file_name}.png', "png")
psimage.close()
Keep in mind the pixels are not the size of a 'real' pixel, they are much bigger and changing the format to 'png' or 'jpg' didn't solve the problem.
If someone knows the solution to this problem, I will greatly appreciate it.
Sorry for the missing information, hopefully this is enough.
Img.ps file as text
And this is how the code generates the .ps file
import tkinter as tk
import random
from save import saveFile
pixels = []
FIELD_SIZE = (1280, 720)
PIXEL_SIZE = 10
class random_pixels():
def draw_full_screen(canvas):
height = round(FIELD_SIZE[1] / PIXEL_SIZE)
width = round(FIELD_SIZE[0] / PIXEL_SIZE)
for y in range(height):
for x in range(width):
color = ["#"+''.join([random.choice('ABCDEF0123456789') for i in range(6)])]
# color = "#444"
x_top_left = x * PIXEL_SIZE + 1
y_top_left = y * PIXEL_SIZE + 1
x_bottom_right = x_top_left + PIXEL_SIZE - 1
y_bottom_right = y_top_left + PIXEL_SIZE - 1
resolution = width * height
util.draw_pixel(canvas, color, x_top_left, x_bottom_right, y_top_left, y_bottom_right, resolution)
canvas.update()
canvas.update()
print("\nPixels drawn!")
print("\nSaving image...")
saveFile(canvas)
canvas.focus_set()
print('\nImage saved!')
class util:
def draw_pixel(canvas:tk.Canvas, color, x0, x, y0, y, pixels_to_draw=1):
pixel = canvas.create_rectangle(x0, y0, x, y, fill=color, outline=color)
pixels.append(pixel)
print(f"{len(pixels)}/{pixels_to_draw} | { round(len(pixels) / pixels_to_draw * 100, 2)}%")
return None
def get_theme(e, canvas, root):
if len(pixels) != 0:
canvas.delete('all')
pixels.clear()
root.focus_set()
if e.char == "g":
random_pixels.draw_full_screen(canvas)
canvas.focus_set()

How can I improve my detection efficiency when flann?

I'm trying to improve the speed of my object detection. I'm using OpenCV and ORB brute force keypoint matching.
I've got 30 seconds for keypoint_detection to run and at the moment it's taking about 23 seconds. This is fine for now with 74 images, but that number is likely to increase.
So far I've;
Reduced my search area down to the absolute minimum
Refined my 74 images down to the absolute minimum size possible
I tried pre-processing to remove some of the clutter from the matching but it impacted my ability to find a successful match dramatically.
I've also tried;
SIF, SURF, MatchTemplate, Canny and a few other methods. ORB brute force is my best match by a significant margin.
This is my exact working code, not pseudo-code and not an MVP as I didn't think it would make sense presenting a cut down version of the code I'm looking to speed up.
Is there any way to improve the efficiency of my code?
import cv2 as cv
import os
import glob
import pyautogui as py
from time import sleep
from windowcapture import WindowCapture
from vision import Vision
# Change the working directory to the folder this script is in.
os.chdir(r'C:\test')
avoid = glob.glob(r"C:\Users\test\*.png")
def loadImages(directory):
# Intialise empty array
image_list = []
# Add images to array
for i in directory:
img = cv.imread(i, cv.IMREAD_UNCHANGED)
image_list.append((img, i))
return image_list
# initialize the WindowCapture class
wincap = WindowCapture()
def keypoint_detection(image_list):
counter = 0
for i in image_list:
counter += 1
needle_img = i[0]
# load image to find
objectToFind = Vision(needle_img)
# get an updated image of the screen
keypoint_haystack = wincap.get_haystack()
# crop the image
x, w, y, h = [600,700,20,50]
keypoint_haystack = keypoint_haystack[y:y+h, x:x+w]
kp1, kp2, matches, match_points = objectToFind.match_keypoints(keypoint_haystack, sliced_name, min_match_count=30)
match_image = cv.drawMatches(objectToFind.needle_img, kp1, keypoint_haystack, kp2, matches, None)
if match_points:
# find the center point of all the matched features
center_point = objectToFind.centeroid(match_points)
# account for the width of the needle image that appears on the left
center_point[0] += objectToFind.needle_w
# drawn the found center point on the output image
match_image = objectToFind.draw_crosshairs(match_image, [center_point])
sleep(3)
break
while(True):
ships_to_avoid = loadImages(avoid)
keypoint_detection(ships_to_avoid)
WindowCapture Class
import numpy as np
import win32gui, win32ui, win32con
class WindowCapture:
# properties
w = 0
h = 0
hwnd = None
cropped_x = 0
cropped_y = 0
offset_x = 0
offset_y = 0
# constructor
def __init__(self, window_name=None):
# find the handle for the window we want to capture.
# if no window name is given, capture the entire screen
if window_name is None:
self.hwnd = win32gui.GetDesktopWindow()
else:
self.hwnd = win32gui.FindWindow(None, window_name)
if not self.hwnd:
raise Exception('Window not found: {}'.format(window_name))
# get the window size
window_rect = win32gui.GetWindowRect(self.hwnd)
self.w = window_rect[2] - window_rect[0]
self.h = window_rect[3] - window_rect[1]
# account for the window border and titlebar and cut them off
border_pixels = 0
titlebar_pixels = 5
self.w = self.w - border_pixels
self.h = self.h - titlebar_pixels - border_pixels
self.cropped_x = border_pixels
self.cropped_y = titlebar_pixels
# set the cropped coordinates offset so we can translate screenshot
# images into actual screen positions
self.offset_x = window_rect[0] + self.cropped_x
self.offset_y = window_rect[1] + self.cropped_y
def get_haystack(self):
# get the window image data
wDC = win32gui.GetWindowDC(self.hwnd)
dcObj = win32ui.CreateDCFromHandle(wDC)
cDC = dcObj.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, self.w, self.h)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0, 0), (self.w, self.h), dcObj, (self.cropped_x, self.cropped_y), win32con.SRCCOPY)
# convert the raw data into a format opencv can read
# dataBitMap.SaveBitmapFile(cDC, 'debug.bmp')
signedIntsArray = dataBitMap.GetBitmapBits(True)
img = np.fromstring(signedIntsArray, dtype='uint8')
img.shape = (self.h, self.w, 4)
# free resources
dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(self.hwnd, wDC)
win32gui.DeleteObject(dataBitMap.GetHandle())
img = img[...,:3]
img = np.ascontiguousarray(img)
return img
#staticmethod
def list_window_names():
def winEnumHandler(hwnd, ctx):
if win32gui.IsWindowVisible(hwnd):
print(hex(hwnd), win32gui.GetWindowText(hwnd))
win32gui.EnumWindows(winEnumHandler, None)
# translate a pixel position on a screenshot image to a pixel position on the screen.
# pos = (x, y)
def get_screen_position(self, pos):
return (pos[0] + self.offset_x, pos[1] + self.offset_y)
Vision Class
import cv2 as cv
import numpy as np
class Vision:
# properties
needle_img = None
needle_w = 0
needle_h = 0
# constructor
def __init__(self, needle_img_path):
self.needle_img = needle_img_path
# Save the dimensions of the needle image
self.needle_w = self.needle_img.shape[1]
self.needle_h = self.needle_img.shape[0]
def match_keypoints(self, haystack_screenshot, name, min_match_count, patch_size=32):
orb = cv.ORB_create(edgeThreshold=0, patchSize=patch_size)
keypoints_needle, descriptors_needle = orb.detectAndCompute(self.needle_img, None)
orb2 = cv.ORB_create(edgeThreshold=0, patchSize=patch_size, nfeatures=2000)
keypoints_haystack, descriptors_haystack = orb2.detectAndCompute(haystack_screenshot, None)
FLANN_INDEX_LSH = 6
index_params = dict(algorithm=FLANN_INDEX_LSH, table_number=6, key_size=12, multi_probe_level=1)
search_params = dict(checks=50)
try:
flann = cv.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(descriptors_needle, descriptors_haystack, k=2)
except cv.error:
return None, None, [], []
# store all the good matches as per Lowe's ratio test.
good = []
points = []
for pair in matches:
if len(pair) == 2:
if pair[0].distance < 0.7*pair[1].distance:
good.append(pair[0])
if len(good) > min_match_count:
print(str(name) + ' - ' + '%03d keypoints matched - %03d' % (len(good), len(keypoints_needle)))
for match in good:
points.append(keypoints_haystack[match.trainIdx].pt)
return keypoints_needle, keypoints_haystack, good, points

grabWindow with hwnd return black screen

Why does grabwindow return black screen? Is a valid window and I do not receive any errors.
pix = QPixmap.grabWindow(hwnd)
And that way it works perfectly!
pix = QPixmap.grabWindow(QApplication.desktop().winId())
Below the complete source code:
def __init__(self):
serverProtocol.RDCServerProtocol.__init__(self)
self._array = QByteArray()
self._buffer = QBuffer(self._array)
self._buffer.open(QIODevice.WriteOnly)
def _makeFramebuffer(self, width, height):
pix = QPixmap.grabWindow(197526) # Google Chrome Window
pix = pix.scaled(width, height)
if width >= self._maxWidth or height >= self._maxHeight:
width = self._maxWidth
height = self._maxHeight
pix.save(self._buffer, 'jpeg')
pixData = self._buffer.data()
self._array.clear()
self._buffer.close()
return "%s" % pixData
I need to capture only the google window, but a black screen appears =/
Thank!

Using pygtk how can I make a simple fullscreen slide show

Using pygtk how can I make a full screen slide show that rotates through all the images in a directory switching them every x seconds
In the past I wrote exactly the same thing. Then I deleted it. This version uses a prepared code for exposing an image while scaling it. It was taken from Jack Valmadre’s Blog
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Taken and customed from Jack Valmadre's Blog:
# http://jackvalmadre.wordpress.com/2008/09/21/resizable-image-control/
#
# Put together and created the time switching by Izidor Matusov <izidor.matusov#gmail.com>
import os
import pygtk
pygtk.require('2.0')
import gtk
import glib
def is_image(filename):
""" File is image if it has a common suffix and it is a regular file """
if not os.path.isfile(filename):
return False
for suffix in ['.jpg', '.png', '.bmp']:
if filename.lower().endswith(suffix):
return True
return False
def resizeToFit(image, frame, aspect=True, enlarge=False):
"""Resizes a rectangle to fit within another.
Parameters:
image -- A tuple of the original dimensions (width, height).
frame -- A tuple of the target dimensions (width, height).
aspect -- Maintain aspect ratio?
enlarge -- Allow image to be scaled up?
"""
if aspect:
return scaleToFit(image, frame, enlarge)
else:
return stretchToFit(image, frame, enlarge)
def scaleToFit(image, frame, enlarge=False):
image_width, image_height = image
frame_width, frame_height = frame
image_aspect = float(image_width) / image_height
frame_aspect = float(frame_width) / frame_height
# Determine maximum width/height (prevent up-scaling).
if not enlarge:
max_width = min(frame_width, image_width)
max_height = min(frame_height, image_height)
else:
max_width = frame_width
max_height = frame_height
# Frame is wider than image.
if frame_aspect > image_aspect:
height = max_height
width = int(height * image_aspect)
# Frame is taller than image.
else:
width = max_width
height = int(width / image_aspect)
return (width, height)
def stretchToFit(image, frame, enlarge=False):
image_width, image_height = image
frame_width, frame_height = frame
# Stop image from being blown up.
if not enlarge:
width = min(frame_width, image_width)
height = min(frame_height, image_height)
else:
width = frame_width
height = frame_height
return (width, height)
class ResizableImage(gtk.DrawingArea):
def __init__(self, aspect=True, enlarge=False,
interp=gtk.gdk.INTERP_NEAREST, backcolor=None, max=(1600,1200)):
"""Construct a ResizableImage control.
Parameters:
aspect -- Maintain aspect ratio?
enlarge -- Allow image to be scaled up?
interp -- Method of interpolation to be used.
backcolor -- Tuple (R, G, B) with values ranging from 0 to 1,
or None for transparent.
max -- Max dimensions for internal image (width, height).
"""
super(ResizableImage, self).__init__()
self.pixbuf = None
self.aspect = aspect
self.enlarge = enlarge
self.interp = interp
self.backcolor = backcolor
self.max = max
self.connect('expose_event', self.expose)
self.connect('realize', self.on_realize)
def on_realize(self, widget):
if self.backcolor is None:
color = gtk.gdk.Color()
else:
color = gtk.gdk.Color(*self.backcolor)
self.window.set_background(color)
def expose(self, widget, event):
# Load Cairo drawing context.
self.context = self.window.cairo_create()
# Set a clip region.
self.context.rectangle(
event.area.x, event.area.y,
event.area.width, event.area.height)
self.context.clip()
# Render image.
self.draw(self.context)
return False
def draw(self, context):
# Get dimensions.
rect = self.get_allocation()
x, y = rect.x, rect.y
# Remove parent offset, if any.
parent = self.get_parent()
if parent:
offset = parent.get_allocation()
x -= offset.x
y -= offset.y
# Fill background color.
if self.backcolor:
context.rectangle(x, y, rect.width, rect.height)
context.set_source_rgb(*self.backcolor)
context.fill_preserve()
# Check if there is an image.
if not self.pixbuf:
return
width, height = resizeToFit(
(self.pixbuf.get_width(), self.pixbuf.get_height()),
(rect.width, rect.height),
self.aspect,
self.enlarge)
x = x + (rect.width - width) / 2
y = y + (rect.height - height) / 2
context.set_source_pixbuf(
self.pixbuf.scale_simple(width, height, self.interp), x, y)
context.paint()
def set_from_pixbuf(self, pixbuf):
width, height = pixbuf.get_width(), pixbuf.get_height()
# Limit size of internal pixbuf to increase speed.
if not self.max or (width < self.max[0] and height < self.max[1]):
self.pixbuf = pixbuf
else:
width, height = resizeToFit((width, height), self.max)
self.pixbuf = pixbuf.scale_simple(
width, height,
gtk.gdk.INTERP_BILINEAR)
self.invalidate()
def set_from_file(self, filename):
self.set_from_pixbuf(gtk.gdk.pixbuf_new_from_file(filename))
def invalidate(self):
self.queue_draw()
class DemoGtk:
SECONDS_BETWEEN_PICTURES = 3
FULLSCREEN = True
WALK_INSTEAD_LISTDIR = True
def __init__(self):
self.window = gtk.Window()
self.window.connect('destroy', gtk.main_quit)
self.window.set_title('Slideshow')
self.image = ResizableImage( True, True, gtk.gdk.INTERP_BILINEAR)
self.image.show()
self.window.add(self.image)
self.load_file_list()
self.window.show_all()
if self.FULLSCREEN:
self.window.fullscreen()
glib.timeout_add_seconds(self.SECONDS_BETWEEN_PICTURES, self.on_tick)
self.display()
def load_file_list(self):
""" Find all images """
self.files = []
self.index = 0
if self.WALK_INSTEAD_LISTDIR:
for directory, sub_directories, files in os.walk('.'):
for filename in files:
if is_image(filename):
filepath = os.path.join(directory, filename)
self.files.append(filepath)
else:
for filename in os.listdir('.'):
if is_image(filename):
self.files.append(filename)
print "Images:", self.files
def display(self):
""" Sent a request to change picture if it is possible """
if 0 <= self.index < len(self.files):
self.image.set_from_file(self.files[self.index])
return True
else:
return False
def on_tick(self):
""" Skip to another picture.
If this picture is last, go to the first one. """
self.index += 1
if self.index >= len(self.files):
self.index = 0
return self.display()
if __name__ == "__main__":
gui = DemoGtk()
gtk.main()
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
Use gtk.Image and gtk.Window.fullscreen().

Categories

Resources