How can i fix transparency in image? PIL - python

when i trying to run this code, my image breaks
User avatar should be transparent
I want make like this:
How can i fix this?
import io
from PIL import Image, ImageDraw
im_rgb = Image.open('cards/customcard1.png')
im_a = Image.new("RGBA", im_rgb.size, 0)
im_a.paste(im_rgb)
draw = ImageDraw.Draw(im_a)
draw.ellipse((92, 193, 403, 504), fill=255)
memberavatar = await _ctx.author.avatar_url.read()
def rounded_avatar(member):
with Image.open(io.BytesIO(member)) as im:
with Image.new("RGBA", im.size) as background:
rgb_avatar = im.convert("RGBA")
with Image.new("L", im.size, 0) as mask:
mask_draw = ImageDraw.Draw(mask)
mask_draw.ellipse([(0, 0), im.size], fill=255)
background.paste(rgb_avatar, (0, 0), mask=mask)
return background
roundedAvatar = rounded_avatar(memberavatar)
roundedAvatar = roundedAvatar.resize((311, 311), Image.ANTIALIAS)
roundedAvatar.save('cards/roundedAva.png')
r = Image.open('cards/roundedAva.png').convert('RGBA')
im_a.paste(r, (92, 193))
im_a.save('C:/Users/RAINGM/desktop/hueta.png')
im_a.show()

I fix this with Image.alpha_composite()

Related

How to make a line to go over image?

I want to make a line to go over image, not to see the end in the left bottom corner. It has no problem when line is not this thick, but with this thickness, I have a problem. How I make line longer?
from PIL import Image, ImageDraw
img = Image.new('RGB', (1000, 1000), (0,0,0))
draw = ImageDraw.Draw(img)
draw.line((1000, -250, 0, 750), (255,0,0), 350)
img
Just move the end of the line further towards the bottom left:
from PIL import Image, ImageDraw
img = Image.new('RGB', (1000, 1000), (0,0,0))
draw = ImageDraw.Draw(img)
draw.line((1000, -250, -500, 1250), (255,0,0), 350)
img.show()
input()
and the end of the line won't be visible anymore

cropping an image in a circular way ang paste on another image, using python

I am trying to crop an image in python in circular shape. And I also want to paste that image on the top of another image, and then then then save the image in a desired format.
This is the image that I want to crop in circular way
This is how the image should be looked like after cropping
This is the image on which I want to paste the circular shaped image
This is my expected output
Here is the code, as far I tried
from PIL import Image, ImageDraw, ImageFilter
im1 = Image.open('rocket.jpg')
im2 = Image.open('lena.jpg')
width, height = im1.size
print(height, width)
mask_im = Image.new("L", im2.size, 0)
draw = ImageDraw.Draw(mask_im)
draw.ellipse((150, 40, 250, 100), fill=255)
mask_im.save('mask_circle.jpg', quality=95)
back_im = im1.copy()
back_im.paste(im2, (0, 0), mask_im)
back_im.save('rocket_pillow_paste_mask_circle.jpg', quality=95)
mask_im_blur = mask_im.filter(ImageFilter.GaussianBlur(10))
mask_im_blur.save('mask_circle_blur.jpg', quality=95)
back_im = im1.copy()
back_im.paste(im2, (0, 0), mask_im_blur)
back_im.save('rocket_pillow_paste_mask_circle_blur.jpg', quality=95)
from PIL import Image, ImageDraw, ImageFilter
im1 = Image.open('rocket.jpg')
im2 = Image.open('lena.jpg')
#height, width, channels = im1.shape
width, height = im1.size
print(height, width)
# ![rocket_pillow_paste_out](data/dst/rocket_pillow_paste_out.jpg)
mask_im = Image.new("L", im2.size, 0)
draw = ImageDraw.Draw(mask_im)
draw.ellipse((140, 50, 260, 170), fill=255)
mask_im.save('mask_circle.jpg', quality=95)
back_im = im1.copy()
back_im.paste(im2, (0, 0), mask_im)
back_im.save('rocket_pillow_paste_mask_circle.jpg', quality=95)
# ![rocket_pillow_paste_mask_circle](data/dst/rocket_pillow_paste_mask_circle.jpg)
mask_im_blur = mask_im.filter(ImageFilter.GaussianBlur(10))
mask_im_blur.save('mask_circle_blur.jpg', quality=95)
back_im = im1.copy()
back_im.paste(im2, (0, 0), mask_im_blur)
back_im.save('rocket_pillow_paste_mask_circle_blur.jpg', quality=95)
# ![rocket_pillow_paste_mask_circle_blur](data/dst/rocket_pillow_paste_mask_circle_blur.jpg)

Ellipse not transparent

I'm trying to crop an image (drawing an ellipse on top) and then paste it on another image.
bg_img = Image.open('bgimgs/light.png')
bg_img = bg_img.resize((600, 420))
root = tk.Tk()
root.withdraw()
image_file = filedialog.askopenfilename()
profile_pic = Image.open(image_file, mode='r')
profile_pic = profile_pic.resize((55, 55))
profile_mask = (55, 55)
mask = Image.new('L', profile_mask, 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((0, 0) + profile_mask, fill=255)
mask = mask.resize(profile_pic.size, Image.ANTIALIAS)
profile_pic.putalpha(mask)
bg_img.paste(profile_pic, (25, 40))
and it produces this.
How can i make the ellipse around picture transparent?

A watermark inside a rectangle which filled the certain color

I want to add a watermark at a picture. But just a text, but a rectangle filled with the black color and a white text inside it.
For now, I only can put a text:
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
img = Image.open("in.jpg")
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-C.ttf", 66)
#font = ImageFont.truetype("Arialbd.ttf", 66)
draw.text((width - 510, height-100),"copyright",(209,239,8), font=font)
img.save('out.jpg')
This will draw the text on a black rectangular background:
from PIL import Image, ImageFont, ImageDraw
img = Image.open("in.jpg")
width, height = img.width, img.height
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(
"/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-C.ttf", 66)
x, y = (width - 510, height-100)
# x, y = 10, 10
text = "copyright"
w, h = font.getsize(text)
draw.rectangle((x, y, x + w, y + h), fill='black')
draw.text((x, y), text, fill=(209, 239, 8), font=font)
img.save('out.jpg')
Using imagemagick, a better looking watermark could be made with
from PIL import Image, ImageFont, ImageDraw
font = ImageFont.truetype(
"/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-C.ttf", 66)
text = "copyright"
size = font.getsize(text)
img = Image.new('RGBA', size=size, color=(0, 0, 0, 0))
draw = ImageDraw.Draw(img)
draw.text((0, 0), text, fill=(209, 239, 8), font=font)
img.save('label.jpg')
and then calling (through subprocess if you wish) something like
composite -dissolve 25% -gravity south label.jpg in.jpg out.jpg
or if you make label with a white background,
composite -compose bumpmap -gravity southeast label.jpg in.jpg out.jpg
To run these commands from within the Python script, you could use subprocess like this:
import subprocess
import shlex
from PIL import Image, ImageFont, ImageDraw
font = ImageFont.truetype(
"/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-C.ttf", 66)
text = "copyright"
size = font.getsize(text)
img = Image.new('RGBA', size=size, color='white')
draw = ImageDraw.Draw(img)
draw.text((0, 0), text, fill=(209, 239, 8), font=font)
img.save('label.jpg')
cmd = 'composite -compose bumpmap -gravity southeast label.jpg in.jpg out.jpg'
proc = subprocess.Popen(shlex.split(cmd))
proc.communicate()

PIL: Thumbnail and end up with a square image

Calling
image = Image.open(data)
image.thumbnail((36,36), Image.NEAREST)
will maintain the aspect ratio. But I need to end up displaying the image like this:
<img src="/media/image.png" style="height:36px; width:36px" />
Can I have a letterbox style with either transparent or white around the image?
PIL already has a function to do exactly that:
from PIL import Image, ImageOps
thumb = ImageOps.fit(image, size, Image.ANTIALIAS)
Paste the image into a transparent image with the right size as a background
from PIL import Image
size = (36, 36)
image = Image.open(data)
image.thumbnail(size, Image.ANTIALIAS)
background = Image.new('RGBA', size, (255, 255, 255, 0))
background.paste(
image, (int((size[0] - image.size[0]) / 2), int((size[1] - image.size[1]) / 2))
)
background.save("output.png")
EDIT: fixed syntax error
from PIL import Image
import StringIO
def thumbnail_image():
image = Image.open("image.png")
image.thumbnail((300, 200))
thumb_buffer = StringIO.StringIO()
image.save(thumb_buffer, format=image.format)
fp = open("thumbnail.png", "w")
fp.write(thumb_buffer.getvalue())
fp.close()
Update of Cesar Canassa's answer.
This will create a thumbnail of image.jpg as image_thumb.jpg:
from PIL import Image, ImageOps
fname = 'image.jpg'
size = (48,48)
thumb = ImageOps.fit(Image.open(fname), size, Image.ANTIALIAS)
thumb.save('{}_thumb.jpg'.format(fname[:fname.rfind('.')]), "JPEG")
Or this, maybe... (forgive spaghetti)
from PIL import Image
def process_image(image, size):
if image.size[0] > size[0] or image.size[1] > size[1]:
#preserve original
thumb = image.copy()
thumb.thumbnail(size,Image.ANTIALIAS)
img = thumb.copy()
img_padded = Image.new("RGBA",size)
img_padded.paste(image,(int((size[0]-image.size[0])/2),int((size[1]-image.size[1])/2)))
return img_padded
Why not simply use the resize method ?
from PIL import Image
image = Image.open('/path/to/img.png')
image = image.resize((36,36), Image.ANTIALIAS)
See recommendations for image resizing in this release note:
https://pillow.readthedocs.io/en/stable/releasenotes/5.3.0.html
you can wrap Nadia's answer in this function, which gives you control over size and background.
def make_square(im, min_size=36, fill_color=(255, 255, 255, 0)):
x, y = im.size
size = min(min_size, x, y)
new_im = Image.new('RGBA', (size, size), fill_color)
im.thumbnail((256, 256))
new_im.paste(im, (int((x - size) / 2), int((y -size) / 2))
return new_im

Categories

Resources