Using the Samsung SPF-87H Digital Photo Frame as a Mini-Monitor under Linux with a Python Program

Sunday, March 11, 2012

Triggered Screenshots

When using a photoframe as a display or a (headless) PC, one might want to update the display at regular intervals, e.g. once per minute to update a clock, but then also at other events, like pressing a key on a keyboard or remote control.

This can be achieved by making the screenshot program listen to UNIX signals. These signals must not be mistaken for signals emitted from GUIs with events like clicking a button, or checking a checkbox. The probably best known of these UNIX signals is SIGINT, which is sent to a program when CTRL-C is pressed, and usually ends the program.

For user defined purposes the signals SIGUSR1 and SIGUSR2 (numerical codes 10 and 12, resp.) have been reserved. In the shell these signals can be send by

kill -SIGUSR1 pid-of-program-to-receive-signal

The tsshot2frame program below will listen to this signal and take a screenshot and send it to the frame when it receives it.

The triggershot program below is just a demo to show how a program can create and send such a signal. In this case the program does it when the key 't' is pressed. Obviously, other events can be used, like key presses on remote control, alarm signals from sensors, etc.
______________________________________________________________________________

#!/usr/bin/python# -*- coding: UTF-8 -*-

# Program: tsshot2frame# based on sshot2frame, but allows to be triggered by a SIGUSR1 signal## This triggered-screenshot-to-frame program takes a screenshot from your desktop# and sends it to the 'Samsung SPF-87H Digital Photo Frame'## The screenshots are taken at regular intervals, but can also be triggered randomly# by a SIGUSR1 signal, to which this program is listening.## It is an extension of the sshot2frame program found here:# http://pyframe.blogspot.com# Read other posts to understand details not commented here# Copyright (C) ullix

# take a screenshot and store into a pixmap #pmap = QtGui.QPixmap.grabWindow(QtGui.QApplication.desktop().winId()) # if you want a screenshot from only a subset of your desktop, you can define it like this pmap = QtGui.QPixmap.grabWindow(QtGui.QApplication.desktop().winId(), x=0, y= 600, width=1200, height=720)

# next code line is needed only when screenshot does not yet have the proper dimensions for the frame # note that distortion will result when aspect ratios of desktop and frame are different! # if not needed then inactivate to save cpu cycles pmap = pmap.scaled(800,480)

# create a buffer object and store the pixmap in it as if it were a jpeg file buffer = QtCore.QBuffer() buffer.open(QtCore.QIODevice.WriteOnly) pmap.save(buffer, 'jpeg') buffer.close()

# now get the just saved "file" data into a string, which we will send to the frame pic = buffer.data().__str__()

# Receiving a signal will interrupt the time.sleep() in the main while loop, # which will result in a shot being taken immediatel<. Therefor a separate # takeshot() is not needed here; it would result in two successive shots # being taken #takeshot()

# Must have a QApplication running to use the other pyqt4 functionsapp = QtGui.QApplication(sys.argv)

# Take screenshots in regular intervals and send them to the frame;# screenshots triggered by SIGNALS will come in additionwhile True: print time.time(), takeshot() time.sleep(60) """ Remember that receiving a SIGNAL will interrupt time.sleep ! From the python documentation: time.sleep(secs) Suspend execution for the given number of seconds. The argument may be a floating point number to indicate a more precise sleep time. The actual suspension time may be less than that requested because any caught signal will terminate the sleep() following execution of that signal’s catching routine. Also, the suspension time may be longer than requested by an arbitrary amount because of the scheduling of other activity in the system. """

Following is the triggershot program:
_______________________________________________________________________________