How to save an Image locally using PIL - python

I am making a program that builds a thumbnail based on user input, and I am running into problems actually saving the image. I am used to C++ where you can simply save the image, it seems that python does not support this.
This is my code right now:
def combine(self):
img = Image.new("RGBA", (top.width,top.height+mid.height+mid.height),(255,255,255))
img.paste(top, (0,0))
img.paste(mid, (0,top.height))
img.paste(bot, (0,top.height+mid.height))
img.show()
img.save("Thumbnail.png", "PNG")
The error that shows up when I run it is :
Traceback (most recent call last):
File "TextToThumbnail.py", line 4, in <module>
class Thumbnail(object):
File "TextToThumbnail.py", line 461, in Thumbnail
img.save("Thumbnail.png", "PNG")
NameError: name 'img' is not defined
What is going on? Preferably I just want to be able to save the image locally, since this program will be running on multiple setups with different pathways to the program.

Related

'TypeError: 'NoneType' object is not subscriptable' in Python while statement

I am a beginner developer just learning Python.
I'm using 'pyautogui' to create a bot that clicks a checkbox.
The code is running just the way I want it to.
But I don't know how to get out of the 'while' statement at the end.
When I click on all the checkboxes I get the following error:
TypeError: 'NoneType' object is not subscriptable
Below is the code I wrote.
import pyautogui
import PIL
pyautogui.sleep(2)
while True:
x1=pyautogui.center(pyautogui.locateOnScreen("checkbox.png", region=(50, 50, 1000, 1000), confidence=0.9))
pyautogui.moveTo(x1)
pyautogui.click()
sftp = pyautogui.locateOnScreen("sftp.png", region=(750, 450, 500, 500), confidence=0.7)
pyautogui.sleep(0.5)
print(x1)
if x1 == None:
break
print("work is done")
Execute the above code and when it's done, the output will be something like this:
Point(x=212, y=859)
Point(x=212, y=877)
Traceback (most recent call last):
File "c:\project\a_\experi.py", line 7, in <module>
x1=pyautogui.center(pyautogui.locateOnScreen("checkbox.png", region=(50, 50, 1000, 1000), confidence=0.9))
File "c:\python39-32\lib\site-packages\pyscreeze\__init__.py", line 581, in center
return Point(coords[0] + int(coords[2] / 2), coords[1] + int(coords[3] / 2))
TypeError: 'NoneType' object is not subscriptable
From the official documentation of PyAutoGUI, we can see that the locateOnScreen() function raises a ImageNotFoundException and returns None when it is unable to locate the image it is searching for. This error might occur due to the following reasons:
If there is an error in the image file name (has to be the same with the original image file name).
If there is an error in the extension of the image file (has to be the same with the original image extension).
If the pixels specified for the image are not matching. Generally, the pixels (region) should be a very close match to the actual image position. A less value for the confidence parameter can be tried to overlook negligible differences between the actual image position and the pixels specified.

Taking Screenshot's using python using the Virtualbox API

I'm trying to take screenshots from my guest Virtualbox session using a python script running in the host. From the research I did the best way of doing this is accessing the VirtualBox API and using COM constants in order to make a screenshot. However, every time I try to run the script I get an attribute error:
Traceback (most recent call last):
File "D:\computer_vision_scripts\take_screenshot.py", line 29, in <module>
take_screenshot('Windows 10 Pro')
File "D:\computer_vision_scripts\take_screenshot.py", line 16, in take_screenshot
machine.LockMachine(session, constants.LockType_Shared)
File "C:\Users\me\AppData\Roaming\Python\Python39\site-packages\win32com\client\__init__.py", line 180, in __getattr__
raise AttributeError(a)
AttributeError: LockType_Shared
The script I am using comes from https://floatingoctothorpe.uk/2018/automating-virtualbox-screenshots-with-python.html
And looks like this when seen in the file version:
import win32com.client
from win32com.client import constants
def take_screenshot(vm_name, screenshot_path='screenshot.png'):
"""Create a VM Screenshot for a given VM"""
vbox = win32com.client.Dispatch("VirtualBox.VirtualBox")
session = win32com.client.Dispatch("VirtualBox.Session")
machine = vbox.FindMachine(vm_name)
machine.LockMachine(session, constants.LockType_Shared)
display = session.Console.Display
width, height, _, _, _, _ = display.GetScreenResolution(0)
screenshot = display.TakeScreenShotToArray(0, width, height,
constants.BitmapFormat_PNG)
session.UnlockMachine()
with open(screenshot_path, 'wb') as output_png:
output_png.write(screenshot.tobytes())
if __name__ == '__main__':
take_screenshot('Windows 10 Pro')
Does anyone know what I should do in order to make it work?
I faced the same issue.
Solved it like this:
Add this:
import virtualbox
from virtualbox import library
Change
machine.LockMachine(session, constants.LockType_Shared)
by
machine.LockMachine(session, virtualbox.library.LockType.shared)
and
screenshot = display.TakeScreenShotToArray(0, width, height,constants.BitmapFormat_PNG)
by
screenshot = display.TakeScreenShotToArray(0, width, height, virtualbox.library.BitmapFormat.png)
Found this solution here:
https://github.com/sethmlarson/virtualbox-python/blob/master/tests/test_test_vm.py

How to change to get python to read images inside multiple folders

I'm trying to display an image in python, and whenever I try, I've gotten this error:
Traceback (most recent call last):
File "C:/Users/Brandon/PycharmProjects/UnstableUnicorns/UnstableUnicorns Test.py", line 15, in <module>
BabyNarwhal = pygame.image.load(r'CardImages\BasicDeck\BabyUnicorns\Baby Narwhal.png').convert()
pygame.error: Couldn't open CardImages\BasicDeck\BabyUnicorns\Baby Narwhal.png
I agree that the image path is a little convoluted, but I can't seem to find a way to get it to load the file. I've tried putting in the whole file path, I've tried to change the read location, but I can't seem to be able to load this image. I really don't want to have to put the images in the same folder as the code since there are a lot of different images I want to display. Here's my code:
import pygame
pygame.init()
xDisplay = 1000
yDisplay = 500
white = (255, 255, 255)
BabyNarwhal = pygame.image.load(r'CardImages\BasicDeck\BabyUnicorns\Baby Narwhal.png').convert()
def main():
display = pygame.display.set_mode((xDisplay, yDisplay))
while True:
display.fill(white)
display.blit(BabyNarwhal, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
pygame.display.update()
main()
and here is the full image path:
C:\Users\Brandon\PycharmProjects\UnstableUnicorns\CardImages\BasicDeck\BabyUnicorns
Using spaces in a filename isn't recommended. And using '/' instead of '\' can resolve the error.
So, you should rename your image without spaces, and use :
babynarwhal_img = pygame.image.load(CardImages/BasicDeck/BabyUnicorns/BabyNarwhal.png).convert()
Note : modified the variable name because of the folder with the same name, can cause problems on certains versions.

Converting python2 PIL to python3 code

A program I'm trying to convert from python2 to python3 uses PIL the python image library.
I try to download a thumbnail from the web to display within a tkinter style gui. Here is, what I think, the offending line of code:
# grab the thumbnail jpg.
req = requests.get(video.thumb)
photo = ImageTk.PhotoImage(Image.open(StringIO(req.content)))
# now this is in PhotoImage format can be displayed by Tk.
plabel = tk.Label(tf, image=photo)
plabel.image = photo
plabel.grid(row=0, column=2)
The program stops and gives a TypeError, here is the backtrce:
Traceback (most recent call last): File "/home/kreator/.local/bin/url-launcher.py", line 281, in <module>
main()
File "/home/kreator/.local/bin/url-launcher.py", line 251, in main
runYoutubeDownloader()
File "/home/kreator/.local/bin/url-launcher.py", line 210, in runYoutubeDownloader
photo = ImageTk.PhotoImage(Image.open(StringIO(req.content)))
TypeError: initial_value must be str or None, not bytes
How do I satisfy python3's requirements here?
In this case you can see that the library you have imported doesn't support Python3. This isn't something you can fix from within your own code.
The lack of Python3 support is because PIL has been discontinued for quite some time now. There is a fork that's actively maintained that I would recommend you use instead: https://pillow.readthedocs.io/
You can download it from pypi.

Attempting to embed a video in pygame using pyglet

im trying to display a video on a pygame surface using the pyglet library to import, play and then convert the frames into an image. I managed to battle my way through installing avbin but now I'm hitting a type error with my code
def cutscene(window_surface, filename):
player = pyglet.media.Player()
source = pyglet.media.load(filename)
player.queue(source)
player.play()
pygame.display.flip()
while True:
window_surface.fill(0)
player.dispatch_events()
tex = player.get_texture()
raw = tex.get_image_data().get_data('RGBA',tex.width*4)
raw = ctypes.string_at(ctypes.addressof(raw), ctypes.sizeof(raw))
img = pygame.image.frombuffer(raw, (tex.width, tex.height), 'RGBA')
window_surface.blit(img, (0,0))
pygame.display.flip()
when I run, i get the following error
Traceback (most recent call last):
File "dino_game.py", line 348, in <module>
main()
File "dino_game.py", line 45, in main
cutscene(window_surface, "Cutscenes/Cutscene1.mov")
File "dino_game.py", line 68, in cutscene
raw = tex.get_image_data().get_data('RGBA',tex.width*4)
AttributeError: 'NoneType' object has no attribute 'get_image_data'
Nothing that I do seems to solve it
EDIT: So after testing both this file and the sample files provided by pyglet, it seems that I get this error no matter what filetype I use, could this be an installation error with pyglet or AVbin?
Gave up trying to use pyglet and swapped to VLC where I just have to pass the window ID for the game and it does the rest for me
VLC script: https://wiki.videolan.org/Python_bindings/

Categories

Resources