I need to resize an image. The original is 1024x768. My laptop screen is set to 1366x768. When I go to view the image the bottom is always cut off. I'm guessing it's because the image is 1024x768 but the image size doesn't take into account the box/window the image sits in, so the bottom of the image gets cuts off as a result.
What is the size, pixelwise, of the box/window and how do I determine the size of my screen, codewise, so I can reset the size of the image so the entire image will fit on the screen and none of it will get cut off. Or is there a way of having the image autoscale so it will fit the screen height resolution? I'm using PIL.
I know I can in the end just
new_image = old_image.resize(x, 768-box_height)
I just need to know the box height.
The most environment-agnostic way is likely to just ask tkinter:
import tkinter #python 3 syntax
root = tkinter.Tk()
root.withdraw()
width, height = root.winfo_screenwidth(), root.winfo_screenheight()
Related
We are using the tkinter library and Image class to display images from a file. In the program we change the pixels (so we have an array with new pixels) and want to display it in the tkinter window as well. (we can't use plt.show() or smth like this, we need to change pixels in Image, because it works only with it)
image = Image.open(files_name)
img = ImageTk.PhotoImage(image)
disp_img.config(image=img)
disp_img.image = img
The best option we've seen is .putpixel. But 1) changing each pixel separately is too long 2) it has a strange parameters, and we are not sure about using it
Probably an unusual question, but I am currently looking for a solution to display image files with PIL slower.
Ideally so that you can see how the image builds up, pixel by pixel from left to right.
Does anyone have an idea how to implement something like this?
It is a purely optical thing, so it is not essential.
Here an example:
from PIL import Image
im = Image.open("sample-image.png")
im.show()
Is there a way to "slow down" im.show()?
AFAIK, you cannot do this directly with PIL's Image.show() because it actually saves your image as a file to /var/tmp/XXX and then passes that file to your OS's standard image viewer to display on the screen and there is no further interaction with the viewer process after that. So, if you draw in another pixel, the viewer will not be aware and if you call Image.show() again, it will save a new copy of your image and invoke another viewer which will give you a second window rather than updating the first!
There are several possibilities to get around it:
use OpenCV's cv2.imshow() which does allow updates
use tkinter to display the changing image
create an animated GIF and start a new process to display that
I chose the first, using OpenCV, as the path of least resistance:
#!/usr/bin/env python3
import cv2
import numpy as np
from PIL import Image
# Open image
im = Image.open('paddington.png')
# Make BGR Numpy version for OpenCV
BGR = np.array(im)[:,:,::-1]
h, w = BGR.shape[:2]
# Make empty image to fill in slowly and display
d = np.zeros_like(BGR)
# Use "x" to avoid drawing and waiting for every single pixel
x=0
for y in range(h):
for x in range(w):
d[y,x] = BGR[y,x]
if x%400==0:
cv2.imshow("SlowLoader",d)
cv2.waitKey(1)
x += 1
# Wait for one final keypress to exit
cv2.waitKey(0)
Increase the 400 near the end to make it faster and update the screen after a greater number of pixels, or decrease it to make it update the screen after a smaller number of pixels meaning you will see them appear more slowly.
As I cannot share a movie on StackOverflow, I made an animated GIF to show how that looks:
I decided to try and do it with tkinter as well. I am no expert on tkinter but the following works just the same as the code above. If anyone knows tkinter better, please feel free to point out my inadequacies - I am happy to learn! Thank you.
#!/usr/bin/env python3
import numpy as np
from tkinter import *
from PIL import Image, ImageTk
# Create Tkinter Window and Label
root = Tk()
video = Label(root)
video.pack()
# Open image
im = Image.open('paddington.png')
# Make Numpy version for simpler pixel access
RGB = np.array(im)
h, w = RGB.shape[:2]
# Make empty image to fill in slowly and display
d = np.zeros_like(RGB)
# Use "x" to avoid drawing and waiting for every single pixel
x=0
for y in range(h):
for x in range(w):
d[y,x] = RGB[y,x]
if x%400==0:
# Convert the video for Tkinter
img = Image.fromarray(d)
imgtk = ImageTk.PhotoImage(image=img)
# Set the image on the label
video.config(image=imgtk)
# Update the window
root.update()
x += 1
I am trying to display png image with transparency on black background, moving it slowly around on surface, but a lot of frames contain white pixels. (that should not be there at all)
The logo surface is created like this:
self.logo_surface = cairo.ImageSurface.create_from_png(image)
And every frame is drawn like this:
I move it to a new position and then scale image down to 15x15px
def draw(self, ctx):
# scale image and move it to a right place
ctx.save()
ctx.translate(self.left, self.top)
ctx.scale(self.scale_xy, self.scale_xy)
ctx.set_source_surface(self.logo_surface)
#Here i tried different filters but without improvement in reducing white flashes
ctx.get_source().set_filter(cairo.FILTER_FAST)
ctx.paint()
ctx.restore()
left, top, scale_xy are float. Left and top are changed a bit every frame.
How could i prevent those flashes?
EDIT:
1)The data from the final surface is extracted using get_data.
buf = self.surface.get_data()
a = numpy.frombuffer(buf, numpy.uint8)
2)This effect does not happen when translate is given integer values:
ctx.translate(int(self.left), int(self.top))
but then the image does not move smoothly anymore on 100x100px surface
The wikimedia logo contained some white pixels between transparent and colored part. Because it is a big picture it cannot be seen unless zoomed very close. If downscaled with cairo, it sometimes happened to use those "white" pixel values - hence flashing white pixels on the image.
If I'm using an image and I want to know the image's size in the file.
There is a function to get the picture's height and width ?
EDIT: Of course I loaded the image to the program with pygame.image.load(PATH).
I believe you need to load the image as a Surface before you can get its width and height. You do that with foo = pygame.image.load(PATHNAME).
Then you can get the width and height by creating a Rectangle with foo.get_rect() and asking the rectangle.
import pygame
foo = pygame.image.load(PATH).get_rect().size
print(foo)
Return the size in a tupple
I'm working with the python graphics module. What I am trying to do is save the current window as an image. In the module there is an option to save an "image" as an image (image.save()). But that isn't helpful because it just saves an image you have already loaded. OR if you load a blank image like I did in hopes drawing over it would change that, surprise, surprise: you get a blank image saved. Here is my code:
from graphics import *
w = 300
h = 300
anchorpoint=Point(150,150)
height=300
width=300
image=Image(anchorpoint, height, width) #creates a blank image in the background
win = GraphWin("Red Circle", w, h)
# circle needs center x, y coordinates and radius
center = Point(150, 150)
radius = 80
circle = Circle(center, radius)
circle.setFill('red')
circle.setWidth(2)
circle.draw(win)
point= circle.getCenter()
print point
pointx= point.getX()
pointy= point.getY()
print pointx
print pointy
findPixel=image.getPixel(150,150)
print findPixel
image.save("blank.gif")
# wait, click mouse to go on/exit
win.getMouse()
win.close()
#######that's it#####
so again here is my problem: How do I save what is now on the screen as "blank.gif"
Thanks!
The objects you are drawing are based on Tkinter. I don't believe you are actually drawing on the base image, but rather simply creating Tkinter objects by using the "graphics" library. I also don't believe you can save a Tkinter to a "gif" file, though you can definitely save them in postscript format, then covert them to a gif format.
In order to do this, you will need python's PIL library.
If all of your objects are actually TKinter objeccts, you can simply save the objects.
Start by replacing this line of code:
image.save("blank.gif")
With the following:
# saves the current TKinter object in postscript format
win.postscript(file="image.eps", colormode='color')
# Convert from eps format to gif format using PIL
from PIL import Image as NewImage
img = NewImage.open("image.eps")
img.save("blank.gif", "gif")
If you need additional information, please check out http://www.daniweb.com/software-development/python/code/216929 - which is where I got the suggested code.
I'm sure there are more elegant solutions available than save/convert, but since I don't know a lot about TKinter - this is the only way I've found.
Hope it helps!