I'm trying to build an application in Python that can draw things on top of video. I have not found a way to do this using gstreamer + Tkinter; I don't think tk lets you do transparent Canvases. So I've looked at using gtk instead, but I'm a bit lost- I would like to be able to just drop some sort of transparent overlay on top and push pixels, but I don't think there's such a thing as a transparent DrawingArea, either. So I need a way to edit the contents of a DrawingArea after each frame of video is in it but before it's shown to the screen. I tried using expose-event but that hasn't worked.
Any suggestions on where to go from here? I want my final product to be a little interface to let the user draw lines and polygons on top of a video as well as drawing pixels programatically- and, if possible, save the result to frames and/or video. So a direction that is more likely to make that possible would be preferred.
Edit: Tried using the "handoff" signal but it flickers madly. PiTiVi has a custom Pipeline that has a state-changed signal which they use to draw lines and circles with Cairo. So this is totally doable...
Edit 2: Right, okay. PiTiVi only draws when the video is paused; I guess I can deal with that. That's what it was using the state changed signal for- you can watch for state change messages and emulate a signal. I can deal with that, but it would be really nice to draw over every frame.
Related
I have tried a bunch of stuff over the last few months to only find the best way is as per the attached image which is to use a fixed container in the window to then carry on as per normal but it then makes it hard to have everything else resize properly.
Just curious if there would happen to be a better way to have the drawing area behind everything else to draw on with out having to use a "fixed" container.
In trying over the last few months if I use say a table then put a drawing area in it fills on of the boxes which is not how i feel it should work for what i am trying to do.
I have found it hard as if i try to resize the window I then have to resize the "fixed" container which is ok but if I try to make the window smaller by the bottom right corner it will not resize, I got round this by hard coding a window size and linking this to a button to "minimize" the window correctly.
If anyone has any pointers to information or has any help to offer that would be great.
If nothing comes up I guess I will keep trying to make it happen as I have worked out so far and have a minimum window size and maximum window size with maybe a x/y input box to customize the window size if required.
Let me make my question more clear. I am making a program where the program simulates a certain set of keypresses in a video game when a certain 'graphic' fully 'charges' up. This graphic is basically a vertical bar that fills up all the way to the top. How can I use python to interpret this graphic and return some info when the bar is visually fully charged up. The position of the graphic on the screen is always consistent and the state of the bar when it is indeed fully charged up, is always the same.
Probably the easiest way to achieve that is to use the ImageGrab module from Pillow.
And then use some pixels in the snapshot to determine if the bar is filling.
Pillow docs - https://pillow.readthedocs.io/en/3.0.x/reference/ImageGrab.html
wxPython 2.8.10, Python 2.6.2, Windows 7 x64
So I am having a bit of a wxPython issue I am hoping someone can say where I am going wrong. In my application I have Sliders where the background colour changes as you move the slider around. I do this via SetBackgroundColour from within a EVT_SLIDER handler. It mostly works, but I end up with a border of unchanged colour around the outer edge of the widget.
I have tried Refresh up the chain, RefreshRect on the top level Frame around the widget (and a few pixels further out), various combinations of Update and Layout, but nothing seems to erase it. The best I have managed is if I use something like:
frame = wx.GetTopLevelParent(slider)
rect = slider.GetRect()
slider.ClearBackground()
slider.SetBackgroundColour(wx.Colour(red,green,blue))
frame.RefreshRect(rect)
It will correctly draw the background box with the new colour without the border issue, but it will not repaint the slider itself.
However, if I click away so the focus is elsewhere, the border snaps to the new colour.
I could probably use an overlay or custom paint function but I am hoping there is something I am missing here that will get me the desired results.
Any suggestions?
(edited to add)
Looks like resizing the window manually corrects the issue, but Layout() does not.
It also functions correctly if you do the client size trick:
w,h = slider.GetClientSize()
slider.SetClientSize( (w+1,h) )
slider.SetClientSize( (w,h) )
I have a GTK drawing area and I want to have an image display as the background for it, while other things can be drawn over it.
My first attempt at this involved me simply taking the image, putting it into a pixmap, and drawing it before I draw other objects. This resulted in the objects backgrounds completely covering my background image.
Now I am thinking I need to change the object's pixmap's gtk.gdk.GC so the background color it has is transparent. Here is where I am having problems. I do not know how to set a gtk.gdk.Color's alpha.
How do I set a gtk.gdk.Color's alpha? (or any other way of making the color transparent)
If this idea seems unlikely to work please let me know. I am pretty new to GTK.
I don't know if this can help you, but my best advice is to use Cairo: an open source 2D graphics library providing cross-platform support for advanced 2D drawing. It is also the easiest way to draw 2D graphics, I think
(I've tried GDK in the past and I thought it was much more tricky to use).
In python you can use the specific bindings Pycairo.
Here you can learn more about it, with easy tutorials.
For your specific problem, see more about images
and trasparency.
The main function for trasparency are:
set_source_rgba(red, green, blue[, alpha=1.0])
paint_with_alpha(alpha)
A great summary to learn how to manage images and transparency is in the example Reflected image in the same page linked before about trasparency.
I'm looking for a way to draw real translucent lines with pygtk or wxPython, I now this is not possible with TKinter (I like this one because its already there). Also, I already now I can do this using PIL, but I want to draw direct to a canvas and it will be a dinamic content so I think using PIL will be a slow solution (and not elegant). Someone know a way to do this? Or maybe another toolkit that allows me to do this.
To get clear what I want is: If I drew lines with distinct colors that overlaps I need to be able to see both lines with a merged color at the intersection. Something like if the color I choose for the pen have a transparence instead of solid color.
Thanks.
Pretty much all "canvas" libraries have brushes with alpha.
PyGTK has the gtk.DrawingArea, often used with cairo.
Cairo can be used with wxPython as well.
QT has the Graphics View Framework.