Pillow: How can i paste a Image on another Image? - python

I'm writing a script that automatically create Quote Image for Instagram. So i want to put an log (logo.png) on the background.
If i run my code i get this error:
$ python main.py
Traceback (most recent call last):
File "main.py", line 17, in <module>
imgbg = bg.paste(logo, (0,0,0,0))
File "C:\Users\bukto\AppData\Local\Programs\Python\Python36-32\lib\site-packages\PIL\Image.py", line 1459, in paste
self.im.paste(im, box)
ValueError: images do not match
Thats my code:
#imports
from PIL import Image
import random
###Generate a Color###
#a list of rgb color codes
colors = [(26, 188, 156),(46, 204, 113),(39, 174, 96),(22, 160, 133),(52, 152, 219),(41, 128, 185),(155, 89, 182),(142, 68, 173),(52, 73, 94),(44, 62, 80),(230, 126, 34),(211, 84, 0),(231, 76, 60),(192, 57, 43)]
bg = Image.new('RGB', (800, 800), random.choice(colors)) #choose a random number out of the list
#add Logo
logo = Image.open("logo.png")
imgbg = bg.paste(logo, (0,0,0,0))
imgbg.save("./img/test.png")
I expect that the logo is in the left top.
If you want to test it yourself here is an git branch:
https://github.com/koehlertimo/QuoteMaker/tree/stackoverflow
Thanks for your support,
Timo Köhler

Your logo.png seems to load as a greyscale with alpha for some reason, so I split it into its constituent parts with:
logo = Image.open("logo.png")
Grey, Alpha = logo.split()
You then paste and save like this:
bg.paste(logo, (0,0), Alpha)
bg.save('result.png')

Related

pillow can not draw text with fill

i draw a text to a image and i set the fill and i get an error , but i do not for the fill it get nothing for my image
from PIL import Image, ImageDraw
img = Image.open('test.png')
d = ImageDraw.Draw(img)
d.text((100, 100), "HELLO", fill="red")
img.save('testssss.png')
Traceback (most recent call last):
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/PIL/ImagePalette.py", line 99, in getcolor
return self.colors[color]
KeyError: (255, 0, 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "main.py", line 20, in <module>
d.text((100, 100), "HELLO", fill="red")
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/PIL/ImageDraw.py", line 455, in text
ink = getink(fill)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/PIL/ImageDraw.py", line 403, in getink
ink, fill = self._getink(fill)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/PIL/ImageDraw.py", line 111, in _getink
ink = self.palette.getcolor(ink)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/PIL/ImagePalette.py", line 109, in getcolor
self.palette[index + 256] = color[1]
IndexError: bytearray index out of range
The image:
my system : replit(linux)
Try, (255,0,0) instead of red.
from PIL import Image, ImageDraw
img = Image.open('test.png')
d = ImageDraw.Draw(img)
d.text((100, 100), "HELLO", fill=(255,0,0))
img.save('testssss.png')
You should also look at the size of your image, it might be too small for the text you are using. You can try reducing from (100,100) to maybe (10,10) first and see if it works.
It could also be a case where you don’t have enough bits for the colour because your image is less than 256 bits per colour palette. You can also try converting your image to an rgb image using the following command before you add the text. Do
img = img.convert("RGB")

python - imagegrab module returns error when using bbox

my image grabber returns an error
ID = randint(111111, 999999)
#Make screenshot and crop on coordinates 162, 187, 91, 206
im = ImageGrab.grab(bbox=(162, 187, 91, 206))
im.save(os.getcwd() + ID + ".png", "PNG")
Returns:
Traceback (most recent call last):
File "DIRECTORY", line 25, in <module>
TextToImage()
File "DIRECTORY", line 13, in TextToImage
im = ImageGrab.grab(bbox=(162, 187, 91, 206))
File "DIRECTORY", line 28, in grab
raise ValueError("bbox x2<=x1")
ValueError: bbox x2<=x1
Help would be greatly appriciated!
The bbox needs something like (top_left_x, top_left_y, bottom_right_x, bottom_right_y). This could be interpreted as [(point A), (pointB)] where point A is smaller than point B. I had a problem with this myself while creating a bbox using the users mouse coordinates. Sometimes the user introduced right_bottom first and caused an error. To solve it I simply compared tuples before adding them.
if tuple(B) < tuple(A):
ordered_tuples = list(B) + list(A)
else:
ordered_tuples = list(A) + list(B)
bbox = tuple(ordered_tuples)
My implementation was different but you should get the point.

AttributeError: load (scapy packet.py)

I've looked around and could not find anything regarding this. The issue is probably due to me being somewhat new to Python and I was hoping I could get some help here.
I came across this blog post from 2009: http://stacksmash.org/2009/09/packet-visualization-with-python/
However when I run this, I get the following error in line 1129 of Scapy's packet.py
$ python test-image.py
Traceback (most recent call last):
File "test-image.py", line 9, in <module>
if(len(pkt.load) > imgWidth):
File "/usr/local/lib/python2.7/dist-packages/scapy/packet.py", line
192, in __getattr__
fld,v = self.getfield_and_val(attr)
File "/usr/local/lib/python2.7/dist-packages/scapy/packet.py", line
189, in getfield_and_val
return self.payload.getfield_and_val(attr)
File "/usr/local/lib/python2.7/dist-packages/scapy/packet.py", line
189, in getfield_and_val
return self.payload.getfield_and_val(attr)
File "/usr/local/lib/python2.7/dist-packages/scapy/packet.py", line
1125, in getfield_and_val
raise AttributeError(attr)
AttributeError: load
Is this maybe an issue with newer library versions (considering this is a blogpost from 2009) or am I missing something here?
This works for me with Python 3.6.4:
from PIL import Image
from scapy.all import rdpcap
capture = rdpcap('./capture.pcap')
imgHeight = len(capture)
imgWidth = max(len(packet) for packet in capture)
imgSize = imgWidth, imgHeight
print('Image Size: ', imgSize)
img = Image.new('RGB', imgSize, (255, 255, 255))
for i in range(0, imgHeight):
for j in range(0, len(capture[i])):
color = ord(str(capture[i])[j])
# print('Writing pixel', (j,i), 'with value:', color)
img.im.putpixel((j,i), (0, color, 0))
img.save('./result.png')

IOError: broken data stream when reading image file

This is the code(a simple python code which could add a number to a picture):
from PIL import Image, ImageDraw, ImageFont
def addnum(number, filepath):
img = Image.open(filepath)
width, height = img.size
draw = ImageDraw.Draw(img)
front_size = height/4
ttf_front = ImageFont.truetype('Arial.ttf', front_size)
draw.text((width - front_size, 0), number, (255, 0, 0), font = ttf_front)
del draw
img.save('wechat_addnum.jpg')
img.show()
if __name__ == '__main__':
addnum('4','wechat.jpg')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/JourneyWoo/anaconda/lib/python2.7/site-packages/spyder/utils/site/sitecustomize.py", line 866, in runfile
execfile(filename, namespace)
File "/Users/JourneyWoo/anaconda/lib/python2.7/site-packages/spyder/utils/site/sitecustomize.py", line 94, in execfile
builtins.execfile(filename, *where)
File "/Users/JourneyWoo/Python/python100/python001/python000.py", line 27, in <module>
addnum('4','wechat.jpg')
File "/Users/JourneyWoo/Python/python100/python001/python000.py", line 16, in addnum
draw = ImageDraw.Draw(img)
File "/Users/JourneyWoo/anaconda/lib/python2.7/site-packages/PIL/ImageDraw.py", line 299, in Draw
return ImageDraw(im, mode)
File "/Users/JourneyWoo/anaconda/lib/python2.7/site-packages/PIL/ImageDraw.py", line 60, in __init__
im.load()
File "/Users/JourneyWoo/anaconda/lib/python2.7/site-packages/PIL/ImageFile.py", line 244, in load
raise_ioerror(err_code)
File "/Users/JourneyWoo/anaconda/lib/python2.7/site-packages/PIL/ImageFile.py", line 59, in raise_ioerror
raise IOError(message + " when reading image file")
IOError: broken data stream when reading image file
I don't know the real problem, and from the google and other questions from stackoverflow I cannot find the method which could solve this problem.
Thank you!!
This is a know issue. Try to update Pillow using pip install Pillow --upgrade

PIL crop and paste problem: Cropping doesn't create a cropped image

I'm trying to crop an image and then paste the cropped image into the centre of another image. Ideally I'd like the cropped image to be smaller than the image its being pasted on so that there is a border around the pasted image but I don't know if that's possible.
Here's what I've tried (along with the resulting error message):
>>> import Image
>>> grey = Image.new('RGB', (200, 200), "grey")
>>> House = Image.open("House01.jpg")
>>> print grey.size, grey.mode, grey.format
>>>(200, 200) RGB None
>>> print House.size, House.mode, House.format
>>>(300, 300) RGB JPEG
>>> box = (25, 25, 25, 25)
>>> House.crop(box)
>>>Image._ImageCrop image mode=RGB size=0x0 at 0x11AD210>
>>> region = House.crop(box)
>>> region.show()
>>>Traceback (most recent call last):
>>> File "<pyshell#28>", line 1, in <module>
region.show()
>>> File "C:\Python26\lib\site-packages\PIL\Image.py", line 1483, in show
_show(self, title=title, command=command)
>>> File "C:\Python26\lib\site-packages\PIL\Image.py", line 2123, in _show
apply(_showxv, (image,), options)
>>> File "C:\Python26\lib\site-packages\PIL\Image.py", line 2127, in _showxv
apply(ImageShow.show, (image, title), options)
>>> File "C:\Python26\lib\site-packages\PIL\ImageShow.py", line 41, in show
if viewer.show(image, title=title, **options):
>>> File "C:\Python26\lib\site-packages\PIL\ImageShow.py", line 66, in show
self.show_image(image, **options)
>>> File "C:\Python26\lib\site-packages\PIL\ImageShow.py", line 85, in show_image
return self.show_file(self.save_image(image), **options)
>>> File "C:\Python26\lib\site-packages\PIL\ImageShow.py", line 81, in save_image
return image._dump(format=self.get_format(image))
>>> File "C:\Python26\lib\site-packages\PIL\Image.py", line 493, in _dump
self.save(file, format)
>>> File "C:\Python26\lib\site-packages\PIL\Image.py", line 1439, in save
save_handler(self, fp, filename)
>>> File "C:\Python26\lib\site-packages\PIL\BmpImagePlugin.py", line 242, in _save
ImageFile._save(im, fp, [("raw", (0,0)+im.size, 0, (rawmode, stride, -1))])
>>> File "C:\Python26\lib\site-packages\PIL\ImageFile.py", line 498, in _save
e.setimage(im.im, b)
>>>SystemError: tile cannot extend outside image
I can see that the 'region' size has been made (0,0) but I can't understand why.
Any help on this would be great thanks
The PIL documentation for the crop method states:
Returns a rectangular region from the
current image. The box is a 4-tuple
defining the left, upper, right, and
lower pixel coordinate.
This is a lazy operation. Changes to
the source image may or may not be
reflected in the cropped image. To get
a separate copy, call the load method
on the cropped copy.
So, you should try region = House.crop(box).load() to make sure you get an actual cropped copy.
UPDATE:
Actually, it seems the above only works if you're using PIL 1.1.6 and later. In versions before that, I guess load() doesn't return anything so you can't chain the operations. In that case, use:
region = House.crop(box)
region.load()
I had a similar error that I could not seem to solve, but I then realized as you did that it had to do with the arguments passed in to Image.crop(). You can see the size of your image is (0,0) so there is nothing to show. You are setting bounds from point (25,25) to (25,25).
If you need a 25x25 cropped image(starting from the top left):
```
>
>> import Image
>>> grey = Image.new('RGB', (200, 200), "grey")
>>> House = Image.open("House01.jpg")
>>> print grey.size, grey.mode, grey.format
>>>(200, 200) RGB None
>>> print House.size, House.mode, House.format
>>>(300, 300) RGB JPEG
>>> box = (0, 0, 25, 25)
>>> House.crop(box)
>>>Image._ImageCrop image mode=RGB size=0x0 at 0x11AD210>
>>> region = House.crop(box)
>>> region.show()
```
If you want to start from the center or another point I would use this link as a reference:

Categories

Resources