Pillow data handling - python

I want to use pillow for saving Image and loading it.
I know I can do Image.save(imagename.xxx).
But I want to save as the contents of images.
and I want to reuse it .
from PIL import Image
import numpy as np
filename = 'any_image.png'
import pickle
im = Image.open(filename)
data = list(im.getdata())
f = open("test_file.dat","wb")
dumps = pickle.dump(data,f)
f = open("test_file.dat","rb")
tumps = pickle.load(f)
print(np.asarray(tumps))
#here
re_im = Image.Image.putdata(tumps)
re_im.show()
I want to show re_im Image Object, it is the same contents I saved before.
I could save & load of the same contents by pickle.
But I don't know where I send the contents.
I want to show the same as original image by re_im.show()
please help me.

I could make it.
first, to omit 'data = list(im.getdata())'
second, to insert 'np.array(im)'
from PIL import Image
import numpy as np
filename = 'any_data.png'
import pickle
im = Image.open(filename)
data = np.array(im)
f = open("test_file.dat","wb")
print(type(data))
dumps = pickle.dump(data,f)
f = open("test_file.dat","rb")
tumps = pickle.load(f)
array = Image.fromarray(tumps)
array.show()

Related

How can I save an image with Image.thumbnail using PIL

Basically, I copied and paste a script, and merged it with other script, and now the script doesn't work, it says an error "NoneType object has no attribute save"Screenshot
And here's the script:
` from PIL import Image
import PIL
import os
from glob import glob
imgs = [y for x in os.walk(".") for y in glob(os.path.join(x[0], '*.png'))]
size = 32, 32
lastdir = None
for file in imgs:
img = Image.open(file)
img = img.thumbnail(size, resample=PIL.Image.NEAREST)
file = file.replace('img', 'icon', 1)
dir = os.path.dirname(file)
try:
os.makedirs(dir)
except:
pass
if dir!=lastdir:
print(dir)
lastdir = dir
img.save(file + ".png", "PNG")`
Resize various images on various directories and save them, but the images are not saving.
The thumbnail() method modifies its object rather than returning a new one. So, this line:
img = img.thumbnail(size, resample=PIL.Image.NEAREST)
should be:
img.thumbnail(size, resample=PIL.Image.NEAREST)

How could I pass my file name through this method?

I am taking a screenshot, and then I need to reference the shot I just took so I can translate what's inside it.
When I directly pass a file location, e.g "filex.png", to readtext, it works, but I just need it to pass the written file into it.
import easyocr
import pyautogui
import time
import cv2
import numpy as np
reader = easyocr.Reader(['en'])
tag = 1
for i in range(2):
time.sleep(4)
image = pyautogui.screenshot(region=(630,400,650,130))
image = cv2.cvtColor(np.array(image),
cv2.COLOR_RGB2BGR)
tag+=1
img = cv2.imwrite(f"image{tag}.png", image)
results = reader.readtext(img)
text=""
for result in results:
text += result[1] + " "
print(text)
In answer to your specific question, I think you're looking for something like:
import easyocr
import pyautogui
import time
import cv2
import numpy as np
reader = easyocr.Reader(['en'])
tag = 1
for i in range(2):
time.sleep(4)
image = pyautogui.screenshot(region=(630, 400, 650, 130))
image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
tag += 1
f_name = f"image{tag}.png"
cv2.imwrite(f_name, image)
results = reader.readtext(f_name)
text = ""
for result in results:
text += result[1] + " "
print(text)
You can just store your file name in a variable in pass it to both imwrite and readtext
There are other options as well, depending on what information you need access to within the program, and how quickly you need to process your data.
Option: Pass the np.array directly to readtext
image = pyautogui.screenshot(region=(630, 400, 650, 130))
image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
results = reader.readtext(image)
Option: Pass the data from the written file to the readtext function.
f_name = f"image{tag}.png"
cv2.imwrite(f_name, image)
with open(f_name, 'rb') as f:
results = reader.readtext(f.read())
import pyautogui
import easyocr
import numpy as np
reader = easyocr.Reader(['en'],gpu=False)
im = pyautogui.screenshot(region=(630,400,650,130)
result = reader.readtext(np.array(im),detail = 0)
just pass the pyautogui image as np.array

PIL Image Open is not able to open some files in a zip folder

I have about 300000 image files in a zip folder. Some of those files have path starting with '__'. PIL function Image.Open() is not able to open these files. Please suggest a way to open them. My code below:
import pandas as pd
import numpy as np
from zipfile import ZipFile
from io import BytesIO
from PIL import Image
from PIL import UnidentifiedImageError
problem_files = []
file_paths = []
img_list = []
img_size = (128,128)
with ZipFile('/XXX/YYY/ZZZ/AI_ML/Project2/words.zip') as myzip:
contents = myzip.namelist()
for i in range(0,len(contents)-1):
text = str(contents[i])
if '.png' in text:
file_paths.append(contents[i])
for path in file_paths:
img = myzip.read(path)
try:
img_data = Image.open(BytesIO(img))
except UnidentifiedImageError:
problem_files.append(path)
img_data = img_data.convert('L')
img_data = img_data.resize(img_size)
image_as_array = np.array(img_data, np.uint8)
image_as_array = np.reshape(image_as_array,(1,-1))
img_list.append(image_as_array)
This puts all the files with path starting with '__' into problem_files list
problem_files[-10:]
['__MACOSX/words/j04/j04-070/._j04-070-08-07.png',
'__MACOSX/words/j04/j04-070/._j04-070-04-07.png',
'__MACOSX/words/j04/j04-070/._j04-070-04-06.png',
'__MACOSX/words/j04/j04-070/._j04-070-08-06.png',
'__MACOSX/words/j04/j04-070/._j04-070-06-03.png',
'__MACOSX/words/j04/j04-070/._j04-070-06-01.png',
'__MACOSX/words/j04/j04-070/._j04-070-08-04.png',
'__MACOSX/words/j04/j04-070/._j04-070-04-04.png',
'__MACOSX/words/j04/j04-070/._j04-070-04-05.png',
'__MACOSX/words/j04/j04-070/._j04-070-08-05.png']
There are about 100000 images in problem_files list

How to create a zip file in memory with a list of PIL image objects?

I am trying to create a zip file in memory with a list of PIL image objects.
import io
from PIL import Image
def get_images(path):
'''This returns a list of PIL images'''
pass
def file_process_im_memory():
images = get_images('mypath')
file_object = io.BytesIO()
file_object2 = io.BytesIO()
images[0].save(file_object, 'PNG')
images[1].save(file_object2, 'PNG')
file_object.seek(0)
file_object2.seek(0)
The image are written in memory, now I want to create an zip file from the in memory image files, I tried below but it didn't work.
zip_file = ZipFile(zip_file_bytes_io, 'w')
for image in images:
file_object = io.BytesIO()
image.save(file_object, 'PNG')
file_object.seek(0)
zip_file.writestr(file_object.getvlaue())
zip_file_bytes_io.seek(0)
I believe this will do what you want. As I said in a now deleted comment, one issue was that the first argument to zip_file.writestr() should be the filename / member name it will be given in the archive with the second one being the data to be written.
In order to be able to do that the image filenames must be preserved. In the code below get_images() now returns a list of [<image file name>, <PIL image object>] pairs of values so the name will be available when writing the in-memory zip file.
import io
import os
from PIL import Image
from pprint import pprint
from zipfile import ZipFile
def get_images(path):
""" Returns a list of image file base name & PIL image object pairs. """
# Harcoded with two images for testing purposes.
IMAGES = (r"C:\vols\Files\PythonLib\Stack Overflow\cookie_cutter_background.png",
r"C:\vols\Files\PythonLib\Stack Overflow\Flying-Eagle.png")
images = []
for image_path in IMAGES:
# Get image file name without extension.
image_name = os.path.splitext(os.path.os.path.basename(image_path))[0]
pil_image = Image.open(image_path)
images.append([image_name, pil_image])
return images
def file_process_in_memory():
""" Converts PIL image objects into BytesIO in-memory bytes buffers. """
images = get_images('mypath')
for i, (image_name, pil_image) in enumerate(images):
file_object = io.BytesIO()
pil_image.save(file_object, "PNG")
pil_image.close()
images[i][1] = file_object # Replace PIL image object with BytesIO memory buffer.
return images # Return modified list.
images = file_process_in_memory()
# Create an in-memory zip file from the in-memory image file data.
zip_file_bytes_io = io.BytesIO()
with ZipFile(zip_file_bytes_io, 'w') as zip_file:
for image_name, bytes_stream in images:
zip_file.writestr(image_name+".png", bytes_stream.getvalue())
pprint(zip_file.infolist()) # Print final contents of in memory zip file.
print('done')
Sample output:
[<ZipInfo filename='cookie_cutter_background.png' filemode='?rw-------' file_size=727857>,
<ZipInfo filename='Flying-Eagle.png' filemode='?rw-------' file_size=462286>]
done

Wand convert pdf to jpeg and storing pages in file-like objects

I am trying to convert a pdf to jpegs using wand, but when I iterate over the SingleImages in image.sequence and save each image separately. I am saving each image on AWS, with database references, using Django.
image_pdf = Image(blob=pdf_blob)
image_jpeg = image_pdf.convert('jpeg')
for img in image_jpeg.sequence:
memory_file = SimpleUploadedFile(
"{}.jpeg".format(img.page_number),
page.container.make_blob())
spam = Spam.objects.create(
page_image=memory_file,
caption="Spam")
This doesn't work, the page.container is calling the parent Image class, and the first page is written over and over again. How do I get the second frame/page for saveing?
Actually, you can get per-file blobs:
for img in image_jpeg.sequence:
img_page = Image(image=img)
Then you can work with each img_page variable like a full-fledged image: change format, resize, save, etc.
It seems you cannot get per file blobs without messing with c_types. So this is my solution
from path import path # wrapper for os.path
import re
import tempfile
image_pdf = Image(blob=pdf_blob)
image_jpeg = image_pdf.convert('jpeg')
temp_dir = path(tempfile.mkdtemp())
# set base file name (join)
image_jpeg.save(temp_dir / 'pdf_title.jpeg')
images = temp_dir.files()
sorted_images = sorted(
images,
key=lambda img_path: int(re.search(r'\d+', img_path.name).group())
)
for img in sorted_images:
with open(img, 'rb') as img_fd:
memory_file = SimpleUploadedFile(
img.name,
img_fd.read()
)
spam = Spam.objects.create(
page_image=memory_file,
caption="Spam Spam",
)
tempfile.rmtree(tempdir)
Not as clean as doing it all in memory, but it gets it done.

Categories