How to fix Memory Error while using PIL in Python - python

I'm creating a bot to automate the label making process. i encountered this problem while trying to save (append) multiple images to a pdf. This issue only happens when I'm using a large no. of images and the program works fine if I'm using a few image.
I want to fix this program so that it can process unlimited no. of images and append it to a single pdf file.
from PIL import Image, ImageDraw, ImageFont
import textwrap
import pandas
import datetime
import numpy
import os
from tkinter import filedialog
from tqdm import tqdm_gui
datenow = datetime.datetime.now()
pdate = datenow.strftime("%d-%m-%y")
y = 0
excel = filedialog.askopenfilename(initialdir="/", title="Select A File", filetypes=(("Excel File", "*.xlsx"),("all files", "*.*")))
save_dir = filedialog.askdirectory()
imlist = []
df = pandas.read_excel(excel)
for data in (df.values):
name, no = data
x = 0
while x<no:
x = x+1
y = y+1
LH = len(name)
if LH < 32:
W = 70
Lng = 16
if LH > 32:
W = 53
Lng = 22
name = name.upper()
para = textwrap.wrap(name, width=Lng)
MAX_W, MAX_H = 800, 592
im = Image.open('TFC.jpg')
draw = ImageDraw.Draw(im)
font = ImageFont.truetype('OpenSans-ExtraBold.ttf', W)
current_h, pad = 155, -5
for line in para:
w, h = draw.textsize(line, font=font)
draw.text(((MAX_W - w) / 2, current_h), line, font=font)
current_h += h + pad
imlist.append(im)
im.save(f'{save_dir}/{pdate}{" TF "}{y}.pdf' , save_all=True, append_images=imlist)
os.startfile(save_dir)
The error which I'm getting:
"C:\Users\RAJA MONSINGH\PycharmProjects\Fuzzy\venv\Scripts\python.exe" "C:/Users/RAJA MONSINGH/PycharmProjects/Lable/lable3.py"
Traceback (most recent call last):
File "C:\Users\RAJA MONSINGH\AppData\Roaming\Python\Python38\site-packages\PIL\ImageDraw.py", line 465, in Draw
return im.getdraw(mode)
AttributeError: 'JpegImageFile' object has no attribute 'getdraw'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:/Users/RAJA MONSINGH/PycharmProjects/Lable/lable3.py", line 34, in <module>
draw = ImageDraw.Draw(im)
File "C:\Users\RAJA MONSINGH\AppData\Roaming\Python\Python38\site-packages\PIL\ImageDraw.py", line 467, in Draw
return ImageDraw(im, mode)
File "C:\Users\RAJA MONSINGH\AppData\Roaming\Python\Python38\site-packages\PIL\ImageDraw.py", line 59, in __init__
im.load()
File "C:\Users\RAJA MONSINGH\AppData\Roaming\Python\Python38\site-packages\PIL\ImageFile.py", line 233, in load
s = read(self.decodermaxblock)
File "C:\Users\RAJA MONSINGH\AppData\Roaming\Python\Python38\site-packages\PIL\JpegImagePlugin.py", line 394, in load_read
s = self.fp.read(read_bytes)
MemoryError
Process finished with exit code 1
Files needed to run the program:
https://drive.google.com/file/d/1rS-auW0MHmdjoPlNET71isL8AyEPPyGT/view?usp=sharing

Related

TypeError with ImageMagick

I'm getting a TypeError when I try and run the following code:
import re
from unicodedata import normalize
from docx import Document
from wand.image import Image
from wand.drawing import Drawing
from wand.font import Font
doc = Document("P.docx")
docText = []
for para in doc.paragraphs:
docText.append(para.text)
fullText = "\n".join(docText)
ct = 242
def get(source, begin, end):
try:
start = source.index(len(begin)) + len(begin)
finish = source.index(len(end), len(start))
return source[start:finish]
except ValueError:
return ""
def capitalize(string):
cap = ("".join(j[0].upper() + j[1:]) for j in string)
return cap
def find_matches(text):
return capitalize(
[
m
for m in re.findall(
r"^[^0-9]\s+([^.;]+\s*)+[.;]+", normalize("NFKD", text), re.MULTILINE
)
]
)
with Image(width=300, height=300, psuedo='xc:black') as canvas:
left, top, width, height = 10, 10, 10, 10
for match in find_matches(text=fullText):
ct += 1
match_words = match.split(" ")
match = " ".join(match_words[:-1]) + 'ct'
with Drawing() as context:
context.fill_color = 'white'
context.rectangle(left=left, top=top, width=width, height=height)
font = Font('/System/Library/Fonts/arial.ttf')
context(canvas)
canvas.caption(match)
canvas.save(filename='patdrawTest.png')
The exact error goes as follows:
Traceback (most recent call last):
File "C:\Users\crazy\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\wand\image.py", line 3221, in caption
raise TypeError()
TypeError
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File
"C:/Users/crazy/PycharmProjects/Patents/PatDraw.py", line 54, in
<module>
canvas.caption(match) File "C:\Users\crazy\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\wand\image.py",
line 1061, in wrapped
result = function(self, *args, **kwargs) File "C:\Users\crazy\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\wand\image.py",
line 3223, in caption
raise TypeError('font must be specified or existing in image') TypeError: font must be specified or existing in image
I'm fully at a loss and can't figure it out. Any help would be great.

ImageTk.Photoimage not working as expected

I want to make the user open a file using askopenfile() and assign the image to a variable
code:
from tkinter import *
from tkinter import filedialog
from PIL import ImageTk, Image
root = Tk()
root.title("Forms")
def new_window():
root.filename = filedialog.askopenfilename(title="Select a file", filetypes=[("Png Files", "*.png")])
print(root.filename)
img = ImageTk.PhotoImage(open(root.filename))
btn = Button(text="Click here to open file .", command=new_window).pack()
root.mainloop()
But i get an error.
The output is:
C:\Users\Imtiaz\PycharmProjects\pythonProject\venv\Scripts\python.exe C:/Users/Imtiaz/PycharmProjects/pythonProject/mbox.py
C:/Users/Imtiaz/Pictures/Roblox/RobloxScreenShot20201102_204504924.png
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Imtiaz\pyver\py390\lib\tkinter\__init__.py", line 1885, in __call__
return self.func(*args)
File "C:\Users\Imtiaz\PycharmProjects\pythonProject\mbox.py", line 11, in new_window
img = ImageTk.PhotoImage(open(root.filename))
File "C:\Users\Imtiaz\PycharmProjects\pythonProject\venv\lib\site-packages\PIL\ImageTk.py", line 108, in __init__
mode = Image.getmodebase(mode)
File "C:\Users\Imtiaz\PycharmProjects\pythonProject\venv\lib\site-packages\PIL\Image.py", line 300, in getmodebase
return ImageMode.getmode(mode).basemode
File "C:\Users\Imtiaz\PycharmProjects\pythonProject\venv\lib\site-packages\PIL\ImageMode.py", line 64, in getmode
return _modes[mode]
KeyError: <_io.TextIOWrapper name='C:/Users/Imtiaz/Pictures/Roblox/RobloxScreenShot20201102_204504924.png' mode='r' encoding='cp1252'>
Answer: Thanks to acw1668 I got what the problem was.
error was in:
img = ImageTk.PhotoImage(open(root.filename))
it is supposed to be:
Either ImageTk.PhotoImage(file=root.filename) or ImageTk.PhotoImage(Image.open(root.filename))

Handling JPG format by Pillow

from tkinter import *
from glob import glob
import demoCheck
import random
import quitter
from PIL import ImageTk
gifdir = 'd:/Python/Jupyter/Programming Python/Chap 8 - GUI/pic/'
class buttonpics(Frame):
def __init__(self, parent=None, dir='./gifs/', **kwargs):
Frame.__init__(self, parent, **kwargs)
self.pack()
self.lbl = Label(self, text='None', bg='blue', fg='red')
self.lbl.pack(fill=BOTH)
self.btn = Button(self, text='Press me', bg='white', command=self.draw)
self.btn.pack()
self.quitter = quitter.Quitter(self)
self.quitter.pack(anchor=S)
self.files = glob(dir+'*.jpg')
self.images = [(file, ImageTk.PhotoImage(file=file))
for file in self.files]
def draw(self):
name, photo = random.choice(self.images)
self.btn.config(image=photo)
self.lbl.config(text=name)
buttonpics(dir=gifdir).mainloop()
The codes are trying to load jpg formatted pictures to Tkinter through Pillow's ImageTk module. However, the system generated the following error:
> Traceback (most recent call last): File
> "d:/Python/Jupyter/Programming Python/Chap 8 -
> GUI/buttonpics-func.py", line 31, in <module>
> buttonpics(dir=gifdir).mainloop() File "d:/Python/Jupyter/Programming Python/Chap 8 -
> GUI/buttonpics-func.py", line 22, in __init__
> self.images = [(file, ImageTk.PhotoImage(file=file)) File "d:/Python/Jupyter/Programming Python/Chap 8 -
> GUI/buttonpics-func.py", line 22, in <listcomp>
> self.images = [(file, ImageTk.PhotoImage(file=file)) File "C:\ProgramData\Anaconda3\lib\site-packages\PIL\ImageTk.py", line 89,
> in __init__
> image = _get_image_from_kw(kw) File "C:\ProgramData\Anaconda3\lib\site-packages\PIL\ImageTk.py", line 58,
> in _get_image_from_kw
> return Image.open(source) File "C:\ProgramData\Anaconda3\lib\site-packages\PIL\Image.py", line 2930,
> in open
> raise UnidentifiedImageError( PIL.UnidentifiedImageError: cannot identify image file 'd:/Python/Jupyter/Programming Python/Chap 8 -
> GUI/pic\\IMG_4147.jpg' Exception ignored in: <function
> PhotoImage.__del__ at 0x00000226CF6CFD30> Traceback (most recent call
> last): File
> "C:\ProgramData\Anaconda3\lib\site-packages\PIL\ImageTk.py", line 118,
> in __del__
> name = self.__photo.name AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'
If the extension is changed to png, the program can be run smoothly. Does this result from a compatibility issue with jpg format or there are some other reasons? Thank you for the help!

OsError(err) in PIL Image library using Image.paste

I am doing a small script to paste an image into a black background to have same size images for a dataset. Here is the script:
for file in glob.glob(imagetteDir):
r = str(file)
image = Image.open(file)
img = np.zeros([100,100,3],dtype=np.uint8)
imageio.imwrite('black.tif', img)
black = Image.open('black.tif')
position = ((black.width - image.width), (black.height - image.height))
print(position)
Image.Image.paste(black,image,position)
dirr , name = r.split("imagette")
path1 = name.raplace("Hexagone_resized","Hexagone")
print(path1)
black.save(imagetteresizeDir+path1)
So Image.Image.paste() make the following error that i didnt find how to resolve:
Traceback (most recent call last):
File "C:\Users\user\Documents\Project\segmentation\Imagette creation\resizing.py", line 29, in <module>
Image.Image.paste(black,image)
File "C:\Users\user\Anaconda3\envs\tf_gpu\lib\site-packages\PIL\Image.py", line 1455, in paste
im.load()
File "C:\Users\user\Anaconda3\envs\tf_gpu\lib\site-packages\PIL\TiffImagePlugin.py", line 1070, in load
return self._load_libtiff()
File "C:\Users\user\Anaconda3\envs\tf_gpu\lib\site-packages\PIL\TiffImagePlugin.py", line 1182, in _load_libtiff
raise OSError(err)
OSError: -2
Have you any idea from where it might come?
Thanks in advance for your help

bbox works when inputting exact coordinates within module but fails with variable containing identical data

I'm having an issue trying to make a screen grab of an area defined by lines in a config file:
The following code:
def coordstore(): # check line 1 of config file (screencap name)
f=open('config.txt')
line=f.readlines()
coordstore.x1,coordstore.y1,coordstore.x2,coordstore.y2 = (line[4]).strip(),(line[5]).strip(),(line[6]).strip(),(line[7]).strip() # note: confusing. 0=line 1, 1=line2 etc.
coordstore.coords = coordstore.x1+',',coordstore.y1+',',coordstore.x2+',',coordstore.y2
coordstore.stripped = ' '.join((coordstore.coords))
print(coordstore.stripped)
return(coordstore.stripped)
coordstore()
def screenshot():
import pyscreenshot as ImageGrab2
# part of the screen
if __name__ == '__main__':
im = ImageGrab2.grab(bbox=(coordstore.stripped)) # X1,Y1,X2,Y2
im.save('tc.png')
screenshot()
prints exactly this value: 10, 20, 100, 300
it then fails with this Traceback:
Traceback (most recent call last):
File "file location", line 82, in <module>
screenshot()
File "file location", line 80, in screenshot
im = ImageGrab2.grab(bbox=(coordstore.stripped)) # X1,Y1,X2,Y2
File "PYCHARM\venv\lib\site-packages\pyscreenshot\__init__.py", line 67, in grab
to_file=False, childprocess=childprocess, backend=backend, bbox=bbox)
File "PYCHARM\venv\lib\site-packages\pyscreenshot\__init__.py", line 38, in _grab
x1, y1, x2, y2 = bbox
ValueError: too many values to unpack (expected 4)
If I manually replace (bbox=(coordstore.stripped)) with (bbox=(10, 20, 100, 300)) which is literally identical to what the variable prints, the code works perfectly but is not useful for my needs. What am I not seeing? Thanks for the help!
UPDATE:
I have tried another approach.
def coordstore(): # check line 1 of config file (screencap name)
f=open('config.txt')
line=f.readlines()
coordstore.x1 = (line[4]).strip()
coordstore.y1 = (line[5]).strip()
coordstore.x2 = (line[6]).strip()
coordstore.y2 = (line[7]).strip()
print(coordstore.x1+',', coordstore.y1+',', coordstore.x2+',', coordstore.y2)
return(coordstore.x1, coordstore.y1, coordstore.x2, coordstore.y2)
coordstore()
def screenshot():
import pyscreenshot as ImageGrab2
# part of the screen
if __name__ == '__main__':
im = ImageGrab2.grab(bbox=(coordstore.x1+',', coordstore.y1+',', coordstore.x2+',', coordstore.y2+',')) # X1,Y1,X2,Y2
im.save('tc.png')
screenshot()
This prints
10, 20, 100, 300
but returns the following Traceback errors:
Traceback (most recent call last):
File "module location", line 84, in <module>
screenshot()
File "module location", line 82, in screenshot
im = ImageGrab2.grab(bbox=(coordstore.x1+',', coordstore.y1+',', coordstore.x2+',', coordstore.y2+',')) # X1,Y1,X2,Y2
File "\PYCHARM\venv\lib\site-packages\pyscreenshot\__init__.py", line 67, in grab
to_file=False, childprocess=childprocess, backend=backend, bbox=bbox)
File "\PYCHARM\venv\lib\site-packages\pyscreenshot\__init__.py", line 42, in _grab
raise ValueError('bbox y2<=y1')
ValueError: bbox y2<=y1
As you have mentioned in comments the value of coordstore.stripped is string. And expected argument by ImageGrab2.grab is type of tuple so, first you have to convert it into tuple.
Update the method like this:
def screenshot():
import pyscreenshot as ImageGrab2
# part of the screen
if __name__ == '__main__':
im = ImageGrab2.grab(bbox=tuple(map(int, coordstore.stripped.split(', ')))) # X1,Y1,X2,Y2
im.save('tc.png')

Categories

Resources