Python-spawned subprocess jpgs in new window and exit on completion - python

I have a file containing thus far some 1800 jpegs (it will grow) which I have to search manually for specific features. This requires that I enter a code (1 or 0) to say whether or not the features that I am looking for exist.
Because the features are difficult to define, the images of low quality and as far as we are aware no non-deterministic approach exists to deal with this satisfactorily it has to be coded.
The idea is to open the large_file containing the jpegs, open each of them in a new window one-by-one (so that I can see them), read in data from the screen and then close the new window.
Roughly this looks something like this:
large_file = open (xxxxxx, rb) # contains info identifying jpeg
for jpeg in large_file: # 1800 items now more later
open jpeg in separate window
does image meet the criterion?: # Enter 1 or 0 (say) at console
if (1 or 0):
close window and move to next image
else:
go back and ask for sensible input
large_file.close()
I am running Kubuntu 14.04 with lightdm as the display manager and Python 2.7.6. Browsing Stackoverflow doesn't really get me what I need.
Implementing using Image cause problems because I am not using xv, but lightdm. Several strategies have not worked properly. Clearly the core issue is spawning the new window and then closing it.
Any suggestions? In an ideal world I would prefer not to have to close images manually...
Many thanks

Related

Cycled images in linux/gtk program suddenly stop displaying

I have an extremely simple application for a Raspberry Pi. (It's an educational kiosk for a children's museum if anyone cares.) In python, I have an infinite loop in a thread reading a line from a serial port. Based on the input, I display one of 14 different jpg images. I am not putting all the code here, but it's a very bare-bones GDK application. I have an Arduino feeding the serial port the information to cycle through all the images for debug purposes. In response to the input, I do the following:
self.CurrentImage.set_from_file("image.jpg") # the name here is one of 14
Not to anyone's great surprise, this works. But as I let the Arduino hammer at the input, the screen would randomly show a white image and nothing again after. I checked the standard out window and the data was still coming and the images still being read. And when I say random I mean that at some point in the input-and-display process, it stops displaying. There are no errors being reported. Sometimes I might get 4-5 images in sequence before it dies, or I might make it through the list twice. It's simply not deterministic. My mind wandered to thinking maybe I'm not clearing first and having a memory leak. I made the following amendment:
self.CurrentImage.clear()
self.CurrentImage.set_from_file("image.jpg")
The problem persisted. I decided to scrap the method and go for something that didn't involve reloading images. At startup I created a separate GTK Image widget for each file. Then in response to the input data, I did this:
self.CurrentImage.hide()
self.CurrentImage = self.AlphaImage # or one of the other 13 Images I created
self.CurrentImage.show()
The nice thing about this method is that the image displays much faster. The first method had the screen briefly go white as the image was loaded. However, once again, after a random number of image switches, the window goes white. Diagnostic output shows that the loop is happily reading data and selecting images.
In the original version where I loaded images as needed, there was exactly one widget on the window. So it's not possible that another widget is covering it. The second version has an Image widget for each jpg file. If one is covering another, I should still at least see that image.
I'm good at thinking outside the box, but I admit that Linux is a weak area for me. Nothing is occurring to me to try to make this work. I'd whinge that I'm under time pressure here and children will be disappointed... but it was supposed to be done before Christmas and I only got the final art yesterday. That reminds me that there's one final note and the reason I thought my first method was failing: I created temporary graphics of my own that was one word of black text on a white background. Those images displayed without problem until the screensaver kicked in.
I'm open to any suggestion as to how to track this down and fix it.
Thanks to Sylvester, I figured this one out. The problem isn't how I was updating the images, it was where I was doing it. In the thread catching the serial input was not the place to do it. I reduced the thread to simply reading the line, then did the following:
GLib.idle_add( self.updateImage, lineInput )
then in the function updateImage I did the business logic of selecting the correct image and updating. Problem solved.

gimp python plug in: how to trigger another user input

Situation:
My gimp python plug-in shows the user a drop down box with two options [".jpg", ".png"].
Question:
How to show a second input window with conditional content based on first input?
.jpg --> "Quality" range slider [0 - 100]
.png --> "Compression" range slider [0 - 9]
In different words:
How to trigger a (registered) plug-in WITH user-input-window from within the main function of a plug-in?
Either you build a full GUI with PyGTK (or perhaps tkinter) or you find another way. Typically for this if you stick to the auto-generated dialogs you have the choice between:
a somewhat clumsy dialog that asks for both parameters and will ignore one or the other depending of the image format,
two menu entries for two different dialogs, one for PNG and one for JPG.
On the other hand, I have always use compression level 9 in my PNGs (AFAIK the only benefit of other levels is CPU time, but this is moot in modern machines) so your dialog could only ask for the JPEG quality which would mak it less clumsy.
However... JPEG quality isn't all there is to it and there are actually many options (chroma sub-sampling being IMHO at least as important as quality), and to satisfy all needs you could end up with a rather complex dialog. So you could either:
Just save with the current user's default settings (gimp_file_save())
Get these settings from some .ini file (they are less likely to change than other parameters of your script)
Not save the image and let the user Save/Export to his/her liking (if this isn't a batch processing script)

Change desktop wallpaper on certain monitor? [duplicate]

I'm using:
ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER,
0, "picturefile", 0)
To change the wallpaper.
But I'm wondering if there's any simple way to put different wallpapers on each screen.
This feature isn't standard in windows though, but there are external applications like ultramon that do this. Anyone know how that works?
The way I thought it might work if I join the two images together into one and then make that the wallpaper, but then I still need a way to span one image accross both screens.
Also, how could I grab some info about the monitor setup, the resolution of each screen and their placement? Like what you see in the gui display settings in windows, but in numbers.
After joining the images together into a big image, you have to set the wallpaper mode to tiled to make it so the image spans the desktop (otherwise it will restart on each monitor).
Couple of ways to do this:
a) Using IActiveDesktop (which does not require Active Desktop to be used, don't worry). This is nicest as on Win7 the new wallpaper will fade in.
You create an IActiveDesktop / CLSID_ActiveDesktop COM object and then call SetWallpaper, SetWallpaperOptions and finally ApplyChanges. (As I'm not a Python dev, I'm not sure exactly how you access the COM object, sorry.)
OR:
b) Via the registry. This isn't as nice, but works well enough.
Under HKEY_CURRENT_USER\Control Panel\Desktop set:
TileWallpaper to (REG_SZ) 1 (i.e. the string "1" not the number 1)
WallpaperStyle to (REG_SZ) 0 (i.e. the string "0" not the number 0)
Then call SystemParameterInfo(SPI_SETDESKTOPWALLPAPER...) as you do already.
.
By the way, the code I'm looking at, which uses IActiveDesktop and falls back on the registry if that fails, passes SPIF_UPDATEINIFILE | SPIF_SENDCHANGE as the last argument to SystemParameterInfo; you're currently passing 0 which could be wrong.
EnumDisplayMonitors is the Win32 API for getting details on the monitors, including their screen sizes and positions relative to each other.
That API returns its results via a callback function that you have to provide. (It calls it once for each monitor.) I am not a Python developer so I'm not sure how you can call such a function from Python.
A quick Google for "Python EnumWindows" (EnumWindows being a commonly-used API which returns results in the same way) finds people talking about that, and using a Lambda function for the callback, so it looks like it's possible but I'll leave it to someone who knows more about Python.
Note: Remember to cope with monitors that aren't right next to each other or aren't aligned with each other. Your compiled image may need to have blank areas to make things line up right on all the monitors. If you move one of the monitors around and do a PrtScn screenshot of the whole desktop you'll see what I mean in the result.

Is it possible to save in a file an animation created with Tkinter?

I wanted to use Python to create animations (video) containing text and simple moving geometric objects (lines, rectangles, circles and so on).
In the book titled "Python 2.6 Graphics Cookbook" I found examples using Tkinter library. First, it looked like what I need. I was able to create simple animation but then I realized that in the end I want to have a file containing my animation (in gif or mp4 format). However, what I have, is an application with GUI running on my computer and showing me my animation.
Is there a simple way to save the animation that I see in my GUI in a file?
There is no simple way.
The question Programmatically generate video or animated GIF in Python? has answers related strictly to creating these files with python (ie: it doesn't mention tkinter).
The question How can I convert canvas content to an image? has answers related to saving the canvas as an image
You might be able to take the best answers from those two questions and combine them into a single program.
I've accomplished this before, but not in a particularly pretty way.
Tl;dr save your canvas as an image at each step of the iteration, use external tools to convert from image to gif
This won't require any external dependencies or new packages except having imagemagick already installed on your machine
Save the image
I assume that you're using a Tkinter canvas object. If you're posting actual images to the tk widgets, it will probably be much easier to save them; the tk canvas doesn't have a built-in save function except as postcript. Postscript might actually be fine for making the animation, but otherwise you can
Concurrently draw in PIL and save the PIL image https://www.daniweb.com/software-development/python/code/216929/saving-a-tkinter-canvas-drawing-python
Take a screenshot at every step, maybe using imagegrab http://effbot.org/imagingbook/imagegrab.htm
Converting the images to to an animation
Once the images are saved, I used imagemagick to dump them into either a gif, or into a mpg. You can run the command right from python using How to run imagemagick in the background from python or something similar. It also means that the process is implictely run on a separate thread, so it won't halt your program while it happens. You can query the file to find out when the process is done.
The command
convert ../location/*.ps -quality 100 ../location/animation.gif
should do the trick.
Quirks:
There are some small details, and the process isn't perfect. Imagemagick reads files in order, so you'll need to save the files so that alphabetical and chronological line up. Beware that the name
name9.ps
Is alphabetically greater than
name10.ps
From imagemagick's point of view.
If you don't have imagemagick, you can download it easily (its a super useful command-line tool to have) on linux and mac, and cygwin comes with it on windows. If you're worried about portability... well... PIL isn't standard either
There is a way of doing that, with the "recording screen method", this was explained in other question: "how can you record your screen in a gif?".
Click the link -->LICEcap : https://github.com/lepht/licecap
They say that it's free software for Mac (OS X) and Windows
You could look at Panda3D, but it could be a little over killed for what you need.
I would say you can use Blender3d too but i'm not really sure of how it works. Someone more experimented then me could tell you more about this.

Get content from open window in Linux

I want to collect data and parse it eventually from an open window in linux.
An example- Suppose a terminal window is open. I need to retrieve all the data that appears on that window. After retrieval, I would parse it to get specific commands entered.
So is it possible to do that? If so, how? I would prefer to use python to code this entire thing.
I am making a guess that first I would have to get some sort of ID for the open window and then use some kind of library to get the content from the window whose ID I have got.
Please help. I am quite a newbie.
You can (ab)use the assistive technologies support (for screen readers and such) that exist in the toolkit libraries. Whether it will work is toolkit specific—Gtk and Qt have this support, but others (like Tk, Fltk, etc.) may or may not.
The Linux Desktop Testing Project is a python toolkit for abusing these interfaces for testing GUI applications, so you can either use it or look how it works and do similar thing.
I think the correct answer may be "with some difficulty". Essentially, the contents of a window is a bitmap. This bitmap is drawn on by a whole slew of primitives (including "display this octet-string, using that encoding and a specific font"), but the window contents is still "just pixels".
Getting the "just pixels" is pretty straight-forward, as these things go. You open a session to the X server and say "given me the contents of window W" and it hands it over.
Doing something useful with it is, unfortunately, a completely different matter, as you'd potentially have to (essentially) OCR the bitmap for what you want.
If you decide to take that route, have a look at the source of xwd, as that does, essentially, that.
Do you have some sort of control over the execution of the terminal? In that case, you can use the script command in the terminal session to log all interaction to a file and then read and parse the file.
$ script myfile
Script started, file is myfile
$ ls
...
$ exit
Script done, file is myfile
$ parse_file.py myfile
If the terminal is running inside of screen, you have other options as well. Screen has logging built in, screen -X sends commands to a running screen session (man screen).

Categories