I have a project in Python 2.7 and PyGTK.
I need to create a transparent background window, but still be able to display images (pixmap and mask based) and other objects inside of the window.
I am using the following code, but no image objects are showing up in Ubuntu (Oneric Ocelot), and I'm getting an error, posted below, (though the window otherwise displays, with its button objects). This won't even render in Windows 7 (this error also posted below).
def expose(widget, event):
cr = widget.window.cairo_create()
# Sets the operator to clear which deletes everything below where an object is drawn
cr.set_operator(cairo.OPERATOR_CLEAR)
# Makes the mask fill the entire window
cr.rectangle(0.0, 0.0, *widget.get_size())
# Deletes everything in the window (since the compositing operator is clear and mask fills the entire window
cr.fill()
# Set the compositing operator back to the default
cr.set_operator(cairo.OPERATOR_OVER)
hab_fish_win = gtk.Window()
hab_fish_win.resize(640, 480)
hab_fish_win.set_resizable(False)
hab_fish_win.set_decorated(False)
hab_fish_win.set_has_frame(False)
hab_fish_win.set_position(gtk.WIN_POS_CENTER)
hab_fish_win.set_app_paintable(True)
screen = hab_fish_win.get_screen()
rgba = screen.get_rgba_colormap()
hab_fish_win.set_colormap(rgba)
hab_fish_win.connect('expose-event', expose)
hab_fish_win.show()
WINDOWS 7 RUN:
Traceback (most recent call last): File "C:\Users\user\MousePaw
Games\Word4Word\PYM\fishtest2.py", line 337, in
HAB_FISH() File "C:\Users\user\MousePaw Games\Word4Word\PYM\fishtest2.py", line 100, in init
hab_fish_win.set_colormap(rgba) TypeError: Gtk.Widget.set_colormap() argument 1 must be gtk.gdk.Colormap, not
None
A quick "print rgba" confirms that rgba is "None", thus the error.
UBUNTU "ONERIC OCELOT" RUN:
Gtk Warning: Attempt to draw a drawable with depth 24 to a drawable with depth 32
What is going on? I desperately need that transparent background for the window.
Okay, after hours of research, I have found that Windows does not support this sort of transparency. As for the Linux error, I don't know.
I'm porting to PyGObject, and using another method for my ends. I would suggest readers of this answer look into it.
Related
I'm trying to write a script for Gimp that will crop an image, make a circular selection of what's left, invert the selection, and then delete the selection. I have the cropping, selection, and inversion part done, but the deleting is what's getting me.
(removed old code, see update)
That's the code I have. What's confusing me about the gimp-item-delete code is the item. I understand that I need to define my current selection as the item, but I'm not sure how to do this. If someone could explain how to do this, I would greatly appreciate it! Alternatively, if there's an easier way to do what I'm trying to do (but preferably still in a script), please let me know what you think. My knowledge of this coding is pretty limited, so simple explanations are appreciated.
UPDATE/EDIT:
Here's the (full) updated code:
; XML2 Conversation Portrait Preview Crop
(define (script-fu-xml2-convo-preview image layer)
(gimp-image-undo-group-start image)
(gimp-selection-none image)
(gimp-image-resize image 152 152 -280 -496)
(gimp-layer-resize-to-image-size layer)
(gimp-image-select-ellipse image 0 0 0 152 152)
(gimp-selection-invert image)
(gimp-displays-flush)
(gimp-drawable-edit-clear layer)
(gimp-selection-none image)
(gimp-image-undo-group-end image)
)
; populate script registration information
(script-fu-register
"script-fu-xml2-convo-preview"
"XML2 Conversation Portrait Preview Crop"
"Crops the preview window for XML2 conversation portraits."
"BaconWizard17"
"BaconWizard17"
"September 2021"
"*"
SF-IMAGE "Image" 0
SF-DRAWABLE "Layer" 0
)
; register the script within gimp menu
(script-fu-menu-register "script-fu-xml2-convo-preview" "<Image>/Marvel Mods/Skin Previews/XML2 PC")
So when I'm running this script, it appears to just crop it and doesn't delete the inverted circular selection. However, if I interact with the image in any way (click on it, duplicated it, copy/paste it, undo/redo), it will correct itself and show the properly cropped image with the deleted circular corners. When I first run the script, it also shows the incorrect image up at the top where you can pick which image you're working on, but after interacting with the image it will show the correct image. Here's an example:
The starting image that I create from the clipboard with Ctrl+Shift+V (after screenshotting it from the game using PrtScr):
Then, I run the script, which results in this:
At the top of the screen, the image shows up like this (which is the top left 152x152 pixels of the starting image:
How the image looks once I interact with it in any way (clicking on it, copy/pasting it, duplicating it, undoing/redoing the operation):
The thumbnail at the top of the screen after I interact with the image:
Maybe it's getting hung up on something during the operation? I'm not sure. I understand if this issue is unavoidable, but I would prefer to be able to just run the script and move on rather than having to interact with the image to get it to show up correctly. The image does have an alpha layer when it's pasted in.
gimp-item-delete is a memory/object management thing and is rarely used. What you are looking for is gimp-drawable-edit-clear.
Note that it should be done (together with your final gimp-selection-none) before gimp-image-undo-group-end if you want your whole script to be undone by a single Ctrl-Z.
Edit: It appears that your code works, it's just that the display isn't updated to show the result, which is exactly what gimp-display-flush is meant to do, so why is your code calling it before gimp-drawable-edit-clear? gimp-display-flush ought to be about the last thing done by your script.
I am creating a GTK+ 3 application which draws an animation using Cairo in a GtkDrawingArea widget. I get visual glitches, such as the ones observed in the images below. These appear only for a single frame, there may be none, or one, or more than one per frame. I am asking for help in identifying the possible issue. Here are the details of my code:
In my main method before starting the gtk_main() loop I hook up a timeout.
g_timeout_add(50, queue_draw, gtk_builder_get_object(builder, "window"));
"window" is the id of my GtkWindow. The queue_draw function is as follows:
gboolean queue_draw(gpointer user_data)
{
gtk_widget_queue_draw(GTK_WIDGET(user_data));
return TRUE;
}
I would think that I could pass the GtkDrawingArea object to this function rather than my whole GtkWindow, but the animation disappears in that case. I am also interested comments on this behavior but it is not my main question.
The draw signal of my GtkDrawingArea is hooked to a function gboolean drawing_area_draw(GtkWidget *widget, cairo_t *cr, gpointer user_data). Inside this method I draw my 3D bar chart by a lazy painter's algorithm, each bar being made of three parallelograms, and the bars being drawn in z order.
It is not a problem with my computer failing to keep up with the frame rendering, somehow corrupting a frame buffer. I set the timeout to 1000ms to capture the images below.
I have not made any calls to gtk_widget_set_double_buffered().
I was not able to observe the issue on Windows Subsystem for Linux (WSL) using XMing as the X server, which makes me think it might be a library issue, or some poorly defined behavior.
The first image is of the visual glitch during my program in normal operation. In the second, I modified the code and fixed the height of the bars to a gentle gradient. This gives a much better view of the issue, but it still very puzzling.
development library package details:
$ dpkg --list | egrep 'lib(cairo|gtk).*-dev'
ii libcairo2-dev:amd64 1.15.10-2ubuntu0.1 amd64 Development files for the Cairo 2D graphics library
ii libgtk-3-dev:amd64 3.22.30-1ubuntu3 amd64 development files for the GTK+ library
library metainformation details:
$ pkg-config --modversion gtk+-3.0 glib-2.0 gdk-pixbuf-2.0 cairo
3.22.30
2.58.1
2.36.11
1.15.10
x11 details:
$ xdpyinfo | head -n 5
name of display: :0
version number: 11.0
vendor string: The X.Org Foundation
vendor release number: 12001000
X.Org version: 1.20.1
Linux details (actually Zorin OS 15 not Ubuntu 18.04):
$ uname -a
Linux <hostname> 4.18.0-25-generic #26~18.04.1-Ubuntu SMP Thu Jun 27 07:28:31 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
edit: Here is another very interesting screenshot of the issue.
Fist, calling gtk_widget_queue_draw on the main window makes no sense as only the GtkDrawingArea need to be updated at a high frequency. Redrawing controls you didn't interact with adds overhead for no value.
Next, I see nothing in your UI that wants to have the drawing area redrawn constantly. You should redraw in reaction to events: a parameter value that has changed in your left panel, or the user clicking in the drawing area to change the viewpoint (if that's something you support). You may event fire up a timeout in reaction to control changes and reinitialize that when another one is changed, so that it lets half a second to the user to change all the settings they want and then display the final result instead of the intermediate changes. This can be useful when you have controls with a value that can change fast like the GtkSpinButtons you use.
From your testing, if calling the drawing code every second instead of every 50ms gives you that result, then the problem is most probably in your drawing code, not on the way GTK+ draws it. To make sure that's the case, you can disable the timeout source that redraws, and add a button that when clicked triggers a single redraw. This way the whole frequency thing is out of the equation, and you should still have those rendering bugs.
The next step is to show us the code in the draw signal handler, as the bug probably lays there. If you want to debug it, you probably can split the drawing so that you save the cairo surface you're drawing to in a file after each histogram bar is painted. Then seeing the changes image by image with an image editor, you will see on which image the problem happens. With some logging, you will see which values trigger the problem.
I want to make screenshots on OSX using python. I dont want make full screen shots but only certain rectangles on the screen. Something like (291,305,213,31). I need the correct pixel because afterwards the image files are processed by OCR (python-tesseract) to extract the text.
By the way this is since 6 years the first time I am programming, so far I only know Java a bit. I started yesterday and gave up this morning at 4am. So basically I have no clue yet...For example I still cannot build with Sublime because of path settings, but thats a different story. Cant figure out everything on one day.
I was trying already the following:
- wxPython
But the result are black images, see also:
stackoverflow.com/questions/8644908/take-screenshot-in-python-cross-platform
Additionally it only works in 32-bit mode, but when I do OCR using python-tesseract openCV requires 64-bit....
autopy
when trying to install I got errors, see also:
stackoverflow.com/questions/12993126/errors-while-installing-python-autopy
ImageGrab
only Windows
effbot.org/imagingbook/imagegrab.htm
commandline screencapture
os.system('screencapture test.png')
When I found this I thought, nice but only fullscreen when checking man screencapture. But then I found this: guides.macrumors.c om/screencapture
-R capture screen rect
That would be already enough, but on OSX 10.7.5 I dont have this option. Any ideas?
import Quartz.CoreGraphics
neverfear.org/blog/view/156/OS_X_Screen_capture_from_Python_PyObjC
Create screenshot as CGImage
image = CG.CGWindowListCreateImage(
region,
CG.kCGWindowListOptionOnScreenOnly,
CG.kCGNullWindowID,
CG.kCGWindowImageDefault)
Unfortunately the image is not in file format but a CGImage, no idea how to save as file.
So if possible I would like to use the commandline screencapture with -R if somebody knows how. Just as a start to continue.
Are there any other command line tools available?
What about other libs that I have missed?
Cheers
M
Given that you can get a CGImageRef, you can get its pixel data using the techniques described in Technical Q&A QA1509: Getting the pixel data from a CGImage object. In particular, it shows a function to get the pixel data as a CFDataRef using this function:
CFDataRef CopyImagePixels(CGImageRef inImage) { return CGDataProviderCopyData(CGImageGetDataProvider(inImage)); }
and says:
The pixel data returned by CGDataProviderCopyData has not been color
matched and is in the format that the image is in, as described by the
various CGImageGet functions …
It shows an alternative for getting the pixel data in other formats if you need that.
I would like to run animations in PostScript smoothly. To see what I want, let me switch to PostScript directly. Call ghostscript, and
200 dup scale .5 setgray 0 0 3 3 rectfill
We have now a gray square.
0 setgray 0 1 3 1 rectfill
With a black stripe in it. We will now fill that stripe, one time white
and black in succession:
{1 setgray 0 1 3 1 rectfill 0 setgray 0 1 3 1 rectfill} loop
You will see now some flickering of black and white rectangles that
are smaller than the original black stripe. Ideally, we would see
the original grey square. Or almost. Where can I get such functionality today?
To see a more interesting animation sequence searching for magic
squares of size 5:
wget http://www.complang.tuwien.ac.at/ulrich/gupu/l5.eps.gz
zcat l5.eps.gz | ghostscript -
A couple of years ago I did try to address these issues. But it never went into ghostscript or Xfree. See
this page. Maybe there are some better ideas now?
Edit: After reading the responses so far, let me clarify one issue here. Essentially, there are two independent issues in this question:
How should an animation be viewed from the language level? I believe, the best way is to view each frame as a single page. With copypage incremental changes can be realized with low effort. Sadly, that semantics of copypage is only present in Level 1 and 2. In Level 3, the meaning of copypage changed to showpage. I did - many years ago - a little modification to ghostscript to delay all visible changes up to copypage or showpage. In this manner, a single XCopyArea containing the changed area is performed locally on the server (that is, the display).
How should actual changes on the visual display be synchronized to avoid artefacts that where not present in the graphics described? The irregular flicker you see is not a privilege of PostScript, it seems to be present in any double-buffered system I have seen so far. Just try to program this in whatever system you see fit.
Further edit:
To get the right language level, that is level 1 or 2 do (for ghostscript):
systemdict /.setlanguagelevel known {2 .setlanguagelevel} if
Edit: I am adding this comment to may attract some new postscript contributors.
We explored some of these issues in this thread on comp.lang.postscript.
Since the release of the Level 2 standard, Postscript is a garbage-collected language. You can disable collection of user objects with the fragment -2 vmreclaim, but it doesn't accomplish much. You can disable ALL ghostscript garbage collection by invoking with the -dNOGC option. This should help prevent stalling and spitting with parts of the image.
Ghostscript has a non-standard operator called flushpage, which synchronizes the rendering with the execution. This helps make sure that everything is seen before it's gone.
- flushpage -
On displays, flushes any buffered output, so that it is guaranteed to
show up on the screen; on printers, has no effect
And for timing control, there doesn't seem to be a better way than simple busy-waiting.
/smallpause {
/flushpage where{pop flushpage}if
50 sleep } def
/pagepause {
/flushpage where{pop flushpage}if
1000 sleep } def
/sleep {
usertime add {
10 {
1 100000 div pop %busy
.1 sin 257 cos atan pop %busy busy
} repeat
dup usertime le {exit}if
} loop pop
} def
The where guards around flushpage allow you to send the same code to interpreters other than ghostscript (like a printer).
If you had an actual Display Postscript server, you could use the wait operator instead of busy-waiting.
Although I like (and upvoted) #luserdroog's answer, I don't believe Postscript should be used for animations on this way - I'd rather use some language that can run widgets or display elements that are designed for real time display and user interation - that is not the case of postscript or ghostscript.
I think it would be nice, though, use postscript for aimations for rendering purposes - just rendering a page after each modification on the image, and using an external program to assemble the different pages as animation frames.
Maybe even using postscript as a rendering engine, with the process in another language calling ghostscript to render each frame in realtime. A nice and easy to use multimedia framework to do that could be for example, the Python language with the Pygame module.
Here is a short example using "pure python + pygame".
#! /usr/bin/env python
# coding: utf-8
import pygame
size = 640,480 #(in pixels)
# multiplying factor so that the whole image is 5 units across
factor = size[0] / 5.0
# Inits pygame drawing window
screen = pygame.display.set_mode(size)
# Rectangle drawing function that scales drawing using the factor above
def draw_rect(color, rect):
new_rect = [int (r * factor) for r in rect]
return pygame.draw.rect(screen, color, new_rect)
def main():
draw_rect((128,128,128), (0, 0, 3, 3))
colors = ((255,255,255), (0,0,0))
color_index = 0
while True:
draw_rect(colors[color_index], (0, 1, 3, 1))
pygame.display.flip()
color_index = 1 - color_index
pygame.time.delay(50) # in miliseconds
try:
main()
finally:
pygame.quit()
To execute this, you have to have Python and Pygame (from http://pygame.org - there are ready packages on most linux systems for that)
Pygame's drawing API is much poorer than postscript - if you need more than rectangles
(like bezies, scaling, rotating and shearing the coordinate system, and so on), the way to go is to use Cairo + python + some display library (which might be pygame, GTK+ or qt) . Cairo is a 2D drawing library that inherits from the postscript way. - or, as I said above, to drive a ghostscript external process using Python, having it generating a rle compressed image file to stdout or a ramdrive, and that image read and displayed frame by frame using python + pygame.
Another option is to use HTML5's Canvas, and do everything in Javascript, viewable on a browser. HTML5's Canvas also inherits the Postscript way of drawing.
Instead of using some third party app, I'd like to write an app in Ruby that when invoked, will capture the full screen and save it in c:\screenshot\snap000001.png
The graphic package is readily there, but how can you capture a region from the full screen so as to save it?
This program is to be invoked by some hot-key, such as setting it to be running when CTRL-PrtScn is pressed, or CTRL-CTRL (both control on left and right), or ALT-ALT.
I haven't tried it (I'm not on windows). But you could use Win32::Screenshot.
While looking around, I've found the following, which does the screenshot using that library
width, height, bitmap = Win32::Screenshot.desktop
img_lst = ImageList.new
img_lst.from_blob(bitmap)
img_lst.write('public/screen.png')
And should write your screenshot as a png file.