Convert picture coordinates to window coordinates - python

I am working on Ubuntu,using Python. I have (x,y) which are the image coordinates.I would like to convert them to screen coordinates.The image loads using Qt.Can anyone tell me how this could be done?

QWidgets have mapToGlobal() in C++. I haven't used it in python, but it should work.
So when using it, it will probably look something like this:
QWidget imgContainer
QPoint global_pt
# ... After the image is visible and loaded ...
# Map the top left corner of the image to global screen coordinates
global_pt = imgContainer.mapToGlobal(QPoint(0,0))
Hope that helps.

Related

How to take screenshot of entire display pygame

I am creating a painter software and want the user to be able to save their image after they have finished creating it, so I tried pygame.image.save(pygame.display.get_surface(), "/home/user/screenshot.png"). I made a quick drawing and pressed the key I set which would save the image. I look at the image, and it's only saved the blank display surface, not the pygame.draw.rect()s of the actual drawing. I looked at the following links: How to capture pygame screen? https://gamedev.stackexchange.com/questions/118372/how-can-i-take-a-screenshot-of-a-certain-part-of-the-screen-in-pygame Can python get the screen shot of a specific window? and much more. How would I take a screenshot of the entire display screen along with the drawing? This is my mainloop:
running = True
while running:
updateWindow() # Updates window
clearWindow() # Clears window
checkEvents() # Checks events
redrawItems() # Redraws your drawing
pygame.event.pump()
pygame.display.quit()
pygame.quit()
Try pygame.Surface.copy on the display surface. See docs here.
So if display is your screen, then:
screencopy = display.copy()
should get you a copy of the display image in screencopy. Remember because of double buffering it will give you a copy of what you would see on the screen if you did an display.update() right then, which might be different that what is showing on the screen if you have done things that have not yet been pushed to the screen yet by an update().
You can do this using pygame.image.save(Surface, filename), which you can read more about
here
Below is a simple function that will save a portion of the display as an image.
def Capture(display,name,pos,size): # (pygame Surface, String, tuple, tuple)
image = pygame.Surface(size) # Create image surface
image.blit(display,(0,0),(pos,size)) # Blit portion of the display to the image
pygame.image.save(image,name) # Save the image to the disk**
What this function does is created a pygame surface named image. Then the area (pos,size) is blitted to image at its origin. Finally, pygame.image.save(Surface, filename) will be called and save image to the disk.
For example, if we want to save a 100x100 image named "Capture.png" at the pos 50x50 on the display, name would equal "Capture.png", pos would equal (50,50), and size would equal (100,100), and the function call would look as such:
Capture(display,"Capture.png",(50,50),(100,100))

Manipulate color of QImage - QT

I have one generic icon image, which has an alpha. Lets say a black sphere placed on an square button, with transparancy.
Now I would like to change the color of the icon on the fly, without having several image of sphere_black.png, sphere_red.png etc etc.
Is there a way to colorize the pixmap, respecting the alpha and change HSV on that pixel, for all in the map?
I have something like this, but stuck:
img = QtGui.QImage(kwargs['icon_path']
pxmap = QtGui.QPixmap(img)
for x in range(img.width()):
for y in range(img.height()):
print img.pixel(1, 1), '###'
# ???? #
Any help is appreciated!
QGraphicsColorizeEffect might be what you are looking for. Sadly the QGraphicsEffect class is made to be used with the graphics view framework, it can't easily be applied to a QImage. However there are workarounds for that, as this discussion shows.
The implementation of the effect in QPixmapColorizeFilter::draw() shows how the colourization is done: A coloured rect (with the color having the alpha set to something else than fully opaque) is drawn over the image with QPainter::fillRect(), with an appropriate composition mode set.

When saving turtle graphics to an .eps file, the background color shows on the screen but is not saved in the .eps file

I am new to Python and have been working with the turtle module as a way of learning the language.
Thanks to stackoverflow, I researched and learned how to copy the image into an encapsulated postscript file and it works great. There is one problem, however. The turtle module allows background color which shows on the screen but does not show in the .eps file. All other colors, i.e. pen color and turtle color, make it through but not the background color.
As a matter of interest, I do not believe the import of Tkinter is necessary since I do not believe I am using any of the Tkinter module here. I included it as a part of trying to diagnose the problem. I had also used bgcolor=Orange rather than the s.bgcolor="orange".
No Joy.
I am including a simple code example:
# Python 2.7.3 on a Mac
import turtle
from Tkinter import *
s=turtle.Screen()
s.bgcolor("orange")
bob = turtle.Turtle()
bob.circle(250)
ts=bob.getscreen()
ts.getcanvas().postscript(file = "turtle.eps")
I tried to post the images of the screen and the .eps file but stackoverflow will not allow me to do so as a new user. Some sort of spam prevention. Simple enough to visualize though, screen has background color of orange and the eps file is white.
I would appreciate any ideas.
Postscript was designed for making marks on some medium like paper or film, not raster graphics. As such it doesn't have a background color per se that can be set to given color because that would normally be the color of the paper or unexposed film being used.
In order to simulate this you need to draw a rectangle the size of the canvas and fill it with the color you want as the background. I didn't see anything in the turtle module to query the canvas object returned by getcanvas() and the only alternative I can think of is to read the turtle.cfg file if there is one, or just hardcode the default 300x400 size. You might be able to look at the source and figure out where the dimensions of the current canvas are stored and access them directly.
Update:
I was just playing around in the Python console with the turtle module and discovered that what the canvas getcanvas() returns has a private attribute called _canvas which is a <Tkinter.Canvas instance>. This object has winfo_width() and winfo_height() methods which seem to contain the dimensions of the current turtle graphics window. So I would try drawing a filled rectangle of that size and see if that gives you what you want.
Update 2:
Here's code showing how to do what I suggested. Note: The background must be drawn before any other graphics are because otherwise the solid filled background rectangle created will cover up everything else on the screen.
Also, the added draw_background() function makes an effort to save and later restore the graphics state to what it was. This may not be necessary depending on your exact usage case.
import turtle
def draw_background(a_turtle):
""" Draw a background rectangle. """
ts = a_turtle.getscreen()
canvas = ts.getcanvas()
height = ts.getcanvas()._canvas.winfo_height()
width = ts.getcanvas()._canvas.winfo_width()
turtleheading = a_turtle.heading()
turtlespeed = a_turtle.speed()
penposn = a_turtle.position()
penstate = a_turtle.pen()
a_turtle.penup()
a_turtle.speed(0) # fastest
a_turtle.goto(-width/2-2, -height/2+3)
a_turtle.fillcolor(turtle.Screen().bgcolor())
a_turtle.begin_fill()
a_turtle.setheading(0)
a_turtle.forward(width)
a_turtle.setheading(90)
a_turtle.forward(height)
a_turtle.setheading(180)
a_turtle.forward(width)
a_turtle.setheading(270)
a_turtle.forward(height)
a_turtle.end_fill()
a_turtle.penup()
a_turtle.setposition(*penposn)
a_turtle.pen(penstate)
a_turtle.setheading(turtleheading)
a_turtle.speed(turtlespeed)
s = turtle.Screen()
s.bgcolor("orange")
bob = turtle.Turtle()
draw_background(bob)
ts = bob.getscreen()
canvas = ts.getcanvas()
bob.circle(250)
canvas.postscript(file="turtle.eps")
s.exitonclick() # optional
And here's the actual output produced (rendered onscreen via Photoshop):
I haven't found a way to get the canvas background colour on the generated (Encapsulated) PostScript file (I suspect it isn't possible). You can however fill your circle with a colour, and then use Canvas.postscript(colormode='color') as suggested by #mgilson:
import turtle
bob = turtle.Turtle()
bob.fillcolor('orange')
bob.begin_fill()
bob.circle(250)
bob.begin_fill()
ts = bob.getscreen()
ts.getcanvas().postscript(file='turtle.eps', colormode='color')
Improving #martineau's code after a decade
import turtle as t
Screen=t.Screen()
Canvas=Screen.getcanvas()
Width, Height = Canvas.winfo_width(), Canvas.winfo_height()
HalfWidth, HalfHeight = Width//2, Height//2
Background = t.Turtle()
Background.ht()
Background.speed(0)
def BackgroundColour(Colour:str="white"):
Background.clear() # Prevents accumulation of layers
Background.penup()
Background.goto(-HalfWidth,-HalfHeight)
Background.color(Colour)
Background.begin_fill()
Background.goto(HalfWidth,-HalfHeight)
Background.goto(HalfWidth,HalfHeight)
Background.goto(-HalfWidth,HalfHeight)
Background.goto(-HalfWidth,-HalfHeight)
Background.end_fill()
Background.penup()
Background.home()
BackgroundColour("orange")
Bob=t.Turtle()
Bob.circle(250)
Canvas.postscript(file="turtle.eps")
This depends on what a person is trying to accomplish but generally, having the option to select which turtle to use to draw your background to me is unnecessary and can overcomplicate things so what one can do instead is have one specific turtle (which I named Background) to just update the background when desired.
Plus, rather than directing the turtle object via magnitude and direction with setheading() and forward(), its cleaner (and maybe faster) to simply give the direct coordinates of where the turtle should go.
Also for any newcomers: Keeping all of the constants like Canvas, Width, and Height outside the BackgroundColour() function speeds up your code since your computer doesn't have to recalculate or refetch any values every time the function is called.

Antialiasing PNG resize in Qt?

In a PyQt based GUI program, I'm drawing a few PNG file as QPixmap after resize. So here is basically what happens:
bitmap = QPixmap( "foo.png" )
bitmap.scaleToHeight(38) # original is larger than this
scene.addItem(QGraphicsPixmapItem(bitmap)) # Add to graphics scene
The problem is: afterwards, the bitmap is rather ugly. Is there a way to do this in a antialiasing way?
See the documentation.
bitmap = bitmap.scaledToHeight(38, Qt.SmoothTransformation)

Pygame Set Mouse Cursor from Bitmap

I'm making an image editor using pygame and I was wondering if it was possible to change the mouse cursor to something more suitable (for instance a circle or rectangle) for brushes.
Pygame has a really weird way of doing it that I'm not sure would work very well. Is there a way I can write to a bitmap and then use that?
If there is a way to do it with Python generally, that would work too I suppose.
Another option is to simply hide the cursor, load any arbitrary bitmap that you like and draw it every frame where the cursor is.
You can load cursors in PyGame with pygame.cursors.load_xbm -- that's black and white cursors only, of course, a well-documented limitation of PyGame, per its docs (and I quote):
Pygame only supports black and white
cursors for the system.
For XBM format docs, see e.g. here. You can prep such files e.g. with the PIL library, per its docs.
Since #SapphireSun asked in a comment about another way, I'd like to present a different answer, and this is drawing the cursor manually. I guess this is what #Mizipzor suggests in his answer, so maybe this is just an elaboration.
First Hide the mouse-cursor, then every time the screen-frame is updated, "manually" paint the cursor:
pygame.mouse.set_visible(False) # hide the cursor
# Image for "manual" cursor
MANUAL_CURSOR = pygame.image.load('finger_cursor_16.png').convert_alpha()
# In main loop ~
...
# paint cursor at mouse the current location
screen.blit( MANUAL_CURSOR, ( pygame.mouse.get_pos() ) )
This method allows the PyGame program to have any sort of bitmap for the cursor. There may be some trickiness around getting the "click" hot-spot in the right location, but this could be achieved by setting a transparent cursor, with the hot-spot at the position to match the custom bitmap. See the manual for details.
# transparent 8x8 cursor with the hot-spot at (4,4)
pygame.mouse.set_cursor((8,8),(4,4),(0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0))
I am not sure how I feel about multi-coloured cursors, but at least it's possible.
you could also just simply load a image to replace of draw something instead of it.
For an example:
cursor = pygame.image.load('CURSOR IMAGE FILE HERE')
pygame.mouse.set_visible(False) # hide the cursor
#write this in the loop
coord = pygame.mouse.get_pos()
screen.blit(cursor, coord)
If you just want to replace it with a shape you could just do this:
pygame.mouse.set_visible(False) # hide the cursor
coord = pygame.mouse.get_pos()
pygame.draw.(shape here)(screen, (color), (coord, width, height))
Hope this helped!

Categories