Why cannot python PIL show two images in one program - python

Here is my code:
img = Image.open('data/img.jpg')
lb = Image.open('data/label.png')
img.show('img')
img.close()
lb.show('lb')
lb.close()
After running this program, the first image is successfully showed, but the second image will not be shown unless I comment the code associated with the first image. What is the cause of this problem.

You can multithread to display both at once:
#!/usr/local/bin/python3
from PIL import Image
from threading import Thread
def display(im):
im.show()
im1 = Image.open('1.jpg')
im2 = Image.open('2.jpg')
t1=Thread(target=display,args=(im1,))
t1.start()
t2=Thread(target=display,args=(im2,))
t2.start()
Or you can temporarily concatenate the images into one:
#!/usr/local/bin/python3
from PIL import Image
import numpy as np
im1 = Image.open('1.jpg')
im2 = Image.open('2.jpg')
Image.fromarray(np.hstack((np.array(im1),np.array(im2)))).show()

Related

How to put text on multiple images using python?

from PIL import Image, ImageDraw, ImageFont
import glob
import os
images = glob.glob("directory_path/*.jpg")
for img in images:
images = Image.open(img)
draw = ImageDraw.Draw(images)
font = ImageFont.load_default() #Downloaded Font from Google font
text = "Text on all images from directory"
draw.text((0,150),text,(250,250,250),font=font)
images.save(img)
I have to put text on all images , I have tried above code but its not working
This code worked for me just fine, but the text was hard to read because it was small and white. I did change directory_path to images and put my images in there. The images looked like this, the text is small and on the left side:
Here is the solution
from PIL import Image,ImageDraw,ImageFont
import glob
import os
images=glob.glob("path/*.jpg")
for img in images:
images=Image.open(img)
draw=ImageDraw.Draw(images)
font=ImageFont.load_default()
text="Whatever text"
draw.text((0,240),text,(250,250,250),font=font)
images.save(img)
one possible problem with the code may be that you are using the images variable for saving the list of images and also to iterate through the images.
Try this code, this will work for sure.
from PIL import Image, ImageDraw, ImageFont
import glob
import os
images = glob.glob("new_dir/*.jpg")
print(images)
for img in images:
image = Image.open(img)
draw = ImageDraw.Draw(image)
font = ImageFont.load_default() #Downloaded Font from Google font
text = "Text on all images from directory"
draw.text((0,150),text,fill = 'red' ,font=font)
image.save(img)

How do I edit multiple files in PIL

I was trying to edit alot of images at the same time using pil and python it shows me this error:
my code so far is below
import glob
import PIL
from PIL import Image
image = glob.glob('./*.png')
img = Image.open(image)
img.putalpha(127)
img.save("")
you may try this:
import glob
import PIL
from PIL import Image
for i in glob.glob('./*.png'):
img = Image.open(i)
img.putalpha(127)
img.save("")

How can I convert some png files to a video using OpenCV?

The file appears and when I open it it just closes. I'm on Linux Mint Cinnamon.
import cv2
import numpy as np
import glob
size = (500,500)
img_array = []
for filename in glob.glob('home/user/Desktop/Images/*.png'):
img = cv2.imread(filename)
height, width, layers = img.shape
size = (width,height)
img_array.append(img)
out = cv2.VideoWriter('project.avi',cv2.VideoWriter_fourcc(*'DIVX'), 15, size)
for i in range(len(img_array)):
out.write(img_array[i])
out.release()
cvWaitKey(0)
Your code is fundamentally correct, but openCV video writing seems to be very sensitive to the machine environment, codecs etc.
As an alternative, you might consider the imageio library, for example:
import imageio
writer = imageio.get_writer('movie.mp4')
for img in img_array:
writer.append_data(img)
writer.close()
The examples are here.
Typo error: cvWaitKey(0) to cv2.waitKey(0)

How to resize pasted image inside box in python?

So I've been trying to make a meme bot, in python using PILLOW (a PIL fork) basically it takes a random template and a random source image and puts them together.
So far I managed to make a version which puts the source image adequately in the template, but fails to resize it. Here's my code:
P. S. I mainly code in C, so my python ain't that great
from PIL import Image, ImageOps
import os, random
import re
import linecache
import string
temp_dir = "temp dir"
source_dir = "source dir"
memes_dir = "memes dir"
#Random template & source image
rand_temp = random.choice(os.listdir(temp_dir))
rand_source = random.choice(os.listdir(source_dir))
#template
bot = Image.open(temp_dir + rand_temp)
#source image
top = Image.open(source_dir + rand_source)
width, height = bot.size
size = (width, height)
#Puts Source image in template
meme = ImageOps.fit(top, size, Image.ANTIALIAS)
meme.paste(bot, (0,0), bot)
meme.show()
Is there any way to achieve what I want? Or should I maybe move to another language? Thanks!

Read a base 64 encoded image from memory using OpenCv python library

I'm working on an app that to do some facial recognition from a webcam stream. I get base64 encoded data uri's of the canvas and want to use it to do something like this:
cv2.imshow('image',img)
The data URI looks something like this:
data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7
So, for clarity I've shown what the image looks like so the base64 string is not broken.
<img src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7">
The official doc says, that imread accepts a file path as the argument. From this SO answer, if I do something like:
import base64
imgdata = base64.b64decode(imgstring) #I use imgdata as this variable itself in references below
filename = 'some_image.jpg'
with open(filename, 'wb') as f:
f.write(imgdata)
The above code snippet works and the image file gets generated properly. However I don't think so many File IO operations are feasible considering I'd be doing this for every frame of the stream. I want to be able to read the image into the memory directly creating the img object.
I have tried two solutions that seem to be working for some people.
Using PIL reference:
pilImage = Image.open(StringIO(imgdata))
npImage = np.array(pilImage)
matImage = cv.fromarray(npImage)
I get cv not defined as I have openCV3 installed which is available to me as cv2 module. I tried img = cv2.imdecode(npImage,0), this returns nothing.
Getting the bytes from decoded string and converting it into an numpy array of sorts
file_bytes = numpy.asarray(bytearray(imgdata), dtype=numpy.uint8)
img = cv2.imdecode(file_bytes, 0) #Here as well I get returned nothing
The documentation doesn't really mention what the imdecode function returns. However, from the errors that I encountered, I guess it is expecting a numpy array or a scalar as the first argument. How do I get a handle on that image in memory so that I can do cv2.imshow('image',img) and all kinds of cool stuff thereafter.
I hope I was able to make myself clear.
This is my solution for python 3.7 and without using PIL
import base64
def readb64(uri):
encoded_data = uri.split(',')[1]
nparr = np.fromstring(base64.b64decode(encoded_data), np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
return img
i hope that this solutions works for all
This worked for me on python 2, and doesn't require PIL/pillow or any other dependencies (except cv2):
Edit: for python3 use base64.b64decode(encoded_data) to decode instead.
import cv2
import numpy as np
def data_uri_to_cv2_img(uri):
encoded_data = uri.split(',')[1]
nparr = np.fromstring(encoded_data.decode('base64'), np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
return img
data_uri = "data:image/jpeg;base64,/9j/4AAQ..."
img = data_uri_to_cv2_img(data_uri)
cv2.imshow(img)
You can just use both cv2 and pillow like this:
import base64
from PIL import Image
import cv2
from StringIO import StringIO
import numpy as np
def readb64(base64_string):
sbuf = StringIO()
sbuf.write(base64.b64decode(base64_string))
pimg = Image.open(sbuf)
return cv2.cvtColor(np.array(pimg), cv2.COLOR_RGB2BGR)
cvimg = readb64('R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7')
cv2.imshow(cvimg)
I found this simple solution.
import cv2
import numpy as np
import base64
image = "" # raw data with base64 encoding
decoded_data = base64.b64decode(image)
np_data = np.fromstring(decoded_data,np.uint8)
img = cv2.imdecode(np_data,cv2.IMREAD_UNCHANGED)
cv2.imshow("test", img)
cv2.waitKey(0)
Source : https://gist.github.com/HoweChen/7cdd09b08147133d8e1fbe9b52c24768

Categories