How do i get aspect ratio of system display resolution in python? - python

How do i get aspect ratio of system display resolution in python?
When I check for display resolution in Ubuntu, I see 1024x768(4:3). How do I get aspect ratio 4:3 in Python?

For this answer I used the following resource: How to get the screen size in Tkinter?
The question you're asking is (1) How do I get the screen resolution in Python (2) How do I convert this resolution to a aspect ration. I solved this problem in the following way:
import Tkinter
import Fraction as f
root = Tkinter.Tk()
width = root.winfo_screenwidth()
height = root.winfo_screenheight()
frac = f.Fraction(width,height)
print frac
Note that this gives the lowest denominator. So for a 1680x1050 screen this is 8/5 instead of a possibly expected 16/10.

Related

Getting screen pixels taking into account the scale factor

I'm trying to get my screen size using python. I keep getting the incorrect value because my code is taking into account the scale factor. For example: My screen resolution is set to: 2736 x 1824. My scale factor is 200% so when I execute my code I get 1368 x 912.
import win32api
width = GetSystemMetrics(0)
height = GetSystemMetrics(1)
print('Width:', width)
print('Height:', height)
Is there any way I can get the resolution as shown in my windows settings without the scale factor? I want to be able to read 2736 x 1824.
import ctypes
scaleFactor = ctypes.windll.shcore.GetScaleFactorForDevice(0) / 100
You can get the scale factor via shcore using ctypes.
Then from this you can calculate the real resolution.
ie: scaleFactor 1.25 is 125%
Your application is not DPI aware. Windows has to lie to the application about the dimensions and magnify the GUI to fit the scale.
A quick fix:
import ctypes
ctypes.windll.user32.SetProcessDPIAware()
For an executable it is recommended to set DPI awareness in the manifest file.

How to set picture as background in python? I am only importing Graphics. No pygames or turtles

I checked the document for Graphics.
It says:
Image(anchorPoint, filename)
Constructs an image from contents of the given file, centered at the given anchor point. Can also be called with width and height parameters instead of filename. In this case, a blank (transparent) image is created of the given width and height.
But I tried to type:
window = GraphWin("game", 400, 400)
Image((200,200),"flower.png")
But it doesnt work.
Do I need to import the picture first??Or add it to the window?
Please help.
This normally should work, you missed the anchorPoint
from graphics import *
window = GraphWin("game", 400, 400)
myimage=Image(Point(200,200),"flower.png")
myimage.draw(window)

Python/PyQt4: How do you find the SIZE of a monitor (in inches)?

I'm trying to find the horizontal width of a monitor in inches or cm (not pixels!) to make a small "ruler" program. DPI would work too.
I'm using PyQt4.
try using the QDesktopWidget's width() and height() to get the width and height respectively.
Class reference at QDesktopWidget Class Reference, this will give you the screens size in pixels and then use QX11Info.appDpiX, this will give you the DPI in pixels per inch. Use both the above info to calculate the screen size in inches.
PS: The width() returns the union width, so in case you have multiple screens, it will return union width of all the screens.

python tkinter: how to work with pixels?

using google (and this site) i have seen some similar questions but my problem is still here:
"i want to draw an image (without reading a file) , being able to manipulate every single pixel's colour in that image."
i have seen another question where was suggested to do something like this:
from tkinter import *
A=Tk()
B=Canvas(A)
B.place(x=0,y=0,height=256,width=256)
for a in range(256):
for b in range(256):
B.create_line(a,b,a+1,b+1,fill=pyList[a][b])#where pyList is a matrix of hexadecimal strings
A.geometry("256x256")
mainloop()
in fact this answers my question but... it is extremely slow.
what should i do with a 1920x1080 image ? wait for my death?
so i am asking something to perform the same as the above code but in a faster way
i have found a way to improve the method suggested by jsbueno , it is explained in the page linked :
Why is Photoimage put slow?
It is indeed tricky --
I thought you had to use a Canvas widget, but that has no access to Pixels either.
Image items embedded in the Canvas do have, though. The Tkinter.PhotoImage class
does have a "put" method that accepts a color in hex format and pixel coordinates:
from tkinter import Tk, Canvas, PhotoImage, mainloop
from math import sin
WIDTH, HEIGHT = 640, 480
window = Tk()
canvas = Canvas(window, width=WIDTH, height=HEIGHT, bg="#000000")
canvas.pack()
img = PhotoImage(width=WIDTH, height=HEIGHT)
canvas.create_image((WIDTH/2, HEIGHT/2), image=img, state="normal")
for x in range(4 * WIDTH):
y = int(HEIGHT/2 + HEIGHT/4 * sin(x/80.0))
img.put("#ffffff", (x//4,y))
mainloop()
The good news is that even it being done this way, the updates are "live":
you set pixels on the image, and see them showing up on screen.
This should be much faster than the way drawing higher level lines on screen -
but for lots of pixels it still will be slow, due to a Python function call needed for
every pixel. Any other pure python way of manipulating pixels directly will suffer from that - the only way out is calling primitives that manipulate several pixels at a time in native code from your Python code.
A nice cross-platform library for getting 2d drawing, however poorly documented as well
is Cairo - it would should have much better primitives than Tkinter's Canvas or PhotoImage.
Don't forget to save a reference after canvas.create_image. In some cases, especially when working with the PIL module, python will garbage-collect the image, even though it is being displayed!
Syntax is something like
canvas.create_image((WIDTH/2, HEIGHT/2), image=img)
canvas.image = img

Why does the calculated width and height in pixel of a string in Tkinter differ between platforms?

I have a Python script which needs to calculate the exact size of arbitrary strings displayed in arbitrary fonts in order to generate simple diagrams. I can easily do it with Tkinter.
import Tkinter as tk
import tkFont
root = tk.Tk()
canvas = tk.Canvas(root, width=300, height=200)
canvas.pack()
(x,y) = (5,5)
text = "yellow world"
fonts = []
for (family,size) in [("times",12),("times",24)]:
font = tkFont.Font(family=family, size=size)
(w,h) = (font.measure(text),font.metrics("linespace"))
print "%s %s: (%s,%s)" % (family,size,w,h)
canvas.create_rectangle(x,y,x+w,y+h)
canvas.create_text(x,y,text=text,font=font,anchor=tk.NW)
fonts.append(font) # save object from garbage collecting
y += h+5
tk.mainloop()
The results seem to depend on the version of Python and/or the system:
Python 2.5 Mac 0S X, times 12: (63,12), times 24: (128,24). Python 2.6 Mac OS X, times 12: (64,14), times 24: (127,27). Python 2.6 Windows XP, times 12: (78,19), times 24: (169,36) http://grab.by/grabs/d24a5035cce0d8032ea4e04cb8c85959.png
After Ned Batchelder mentioned it, I discovered that the size of fonts differs from platform to platform. It may not be a deal breaker as long as you stick with Tkinter, which remains consistent with itself. But my complete program does not use Tkinter to perform the actual drawing: it just relies on its font size calculations to generate an output (in SVG or as a Python script to be sent to Nodebox). And it's there that things go really wrong:
Output of mocodo http://grab.by/grabs/f67b951d092dd1f4f490e1469a53bca2.png
(Please look at the image in real size. Note that the main font used for these outputs is not Times, but Trebuchet MS.)
I now suspect that such discrepancies can't be avoided with Tkinter. Which other cross-platform solution would you recommend?
You have two problems. Let's tackle them one at a time
1: the difference between python 2.5 and 2.6 on the same platform with the same font
These two versions of python use different versions of tk. On my mac box, 2.5 uses tk version 8.4.19 and 2.6 uses 8.5.7. In version 8.5.2 of tk were some changes to the font measurement features of tk. Assuming that the changes were improvements, I think it's safe to assume that the numbers you get from python 2.6 are more accurate than the ones from 2.5.
2: the difference between python 2.6 on the mac and 2.6 on the PC.
Obviously, from the screenshots you include, the PC is using a larger font and thus you get larger numbers for the measurement. The question is, why? You are specifying the font size in points (1/72 of an inch). In order for Tk (or any rendering system) to render the font, it needs to know how many pixels are in an inch on the actual display. This will vary on different systems, and Tk isn't always given an accurate number by the underlying OS in order to do its calculations.
Historically, Apple and Microsoft have standardized on 72ppi and 96ppi regardless of the actual display, so the numbers are always going to be different. For more information about the differences in how the mac and windows calculate pixel density see the Dots Per Inch article on wikipedia.
You might try solving this by specifying a font in pixels rather than in points. You can do this by using negative numbers for the font size.
Finally, one thing you might add to your little example code is to print out the result of the font.actual() command -- you might see something different between your windows and mac boxes, which would explain the differences there. This tells you exactly which font is being used by Tk.
After searching for ages I finally found out a way to get the width of some text in any font and size!
from tkinter import *
Window = Tk()
Window.geometry("500x500+80+80")
frame = Frame(Window) # this will hold the label
frame.pack(side = "top")
# CALCULATE:
measure = Label(frame, font = ("Purisa", 10), text = "The width of this in pixels is.....", bg = "yellow")
measure.grid(row = 0, column = 0) # put the label in
measure.update_idletasks() # this is VERY important, it makes python calculate the width
width = measure.winfo_width() # get the width
# PROOF IT WORKS:
canvas = Canvas(frame, width = 400, height = 200, bg = "light green")
canvas.grid(row = 1, column = 0, columnspan = 100) # collumnspan is 100 so that the line lines up with the text
line = canvas.create_line(0, 10, width, 10, width = 4) # make a line the same length as the text
canvas.create_text(10, 20, font = ("Purisa", 10), text = "... "+str(width)+" Pixels", anchor = "nw")
The line I make is proof that this works for any font.
I have tested this for different fonts and sizes, as far as I know it works.
This is a picture of the output:
You haven't done anything wrong: the size of fonts does differ from platform to platform.
I'm not sure why the Python version matters, but the differences are only one pixel, so it could be different rounding or different rendering of the same font.
In tkinter if font size is positive it is in points(1 point (abbreviated pt) is equal to 1/72 of an inch)
if font size is given in negetive values it is in pixels.

Categories

Resources