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
Related
I fount this code off of the PIL API(here is the link: https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html) and I wanted to also shrink it depending on the size of the text while it is centered.
here is the anchoring code
from PIL import Image, ImageDraw, ImageFont
font = ImageFont.truetype("mont.ttf", 48)
im = Image.new("RGB", (200, 200), "white")
d = ImageDraw.Draw(im)
d.text((100, 100), "Quick", fill="black", anchor="ms", font=font)
im.save('text.png')
And the outcome looks like this:
But if you increase the word size it looks like this:
So I just want the text to be centered and shrunk to fit the image
No detail about the requirements, so here only for result image with fixed size (200, 200), so font size will be changed.
Find the size of text by ImageDraw.textsize
Draw on an image with same width as the text by ImageDraw.text
Resize image to (200-2*border, 200-2*border) by Image.resize
Paste the resized image to a 200x200 image by Image.paste
from PIL import Image, ImageDraw, ImageFont
def text_to_image(text, filename='text.png', border=20):
im = Image.new("RGB", (1, 1), "white")
font = ImageFont.truetype("calibri.ttf", 48)
draw = ImageDraw.Draw(im)
size = draw.textsize(text, font=font)
width = max(size)
im = Image.new("RGB", (width, width), "white")
draw = ImageDraw.Draw(im)
draw.text((width//2, width//2), text, anchor='mm', fill="black", font=font)
im = im.resize((200-2*border, 200-2*border), resample=Image.LANCZOS)
new_im = Image.new("RGB", (200, 200), "white")
new_im.paste(im, (border, border))
new_im.show()
# new_im.save(filename)
text_to_image("Hello World")
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)
I use the Pillow (PIL) 6.0 and add text in the image. And I want to put the text in the center of the image. Here is my code,
import os
import string
from PIL import Image
from PIL import ImageFont, ImageDraw, ImageOps
width, height = 100, 100
text = 'H'
font_size = 100
os.makedirs('./{}'.format(text), exist_ok=True)
img = Image.new("L", (width, height), color=0) # "L": (8-bit pixels, black and white)
font = ImageFont.truetype("arial.ttf", font_size)
draw = ImageDraw.Draw(img)
w, h = draw.textsize(text, font=font)
draw.text(((width-w)/2, (height-h)/2), text=text, fill='white', font=font)
img.save('H.png')
Here is the output:
Question:
The text is in the center horizontally, but not in the center vertically. How can I put it in the center horizontally and vertically?
Text always have some added space around characters, e.g. if we create a box that is the exact size reported for your 'H'
img = Image.new("L", (width, height), color=0) # "L": (8-bit pixels, black and white)
font = ImageFont.truetype("arial.ttf", font_size)
draw = ImageDraw.Draw(img)
w, h = draw.textsize(text, font=font)
# draw.text(((width-w)/2, (height-h)/2), text=text, fill='white', font=font)
# img.save('H.png')
img2 = Image.new("L", (w, h), color=0) # "L": (8-bit pixels, black and white)
draw2 = ImageDraw.Draw(img2)
draw2.text((0, 0)), text=text, fill='white', font=font)
img2.save('H.png')
gives the bounding box:
Knowing that line height is normally ~20% larger than the glyphs/characters (+ some trial and error), and we can figure out the extent of the extra space. (The extra space for width is equally distributed so not interesting for centering).
draw2.text((0, 0 - int(h*0.21)), text=text, fill='white', font=font)
which moves the 'H' to the top:
Plugging this back into your original code:
img = Image.new("L", (width, height), color=0) # "L": (8-bit pixels, black and white)
font = ImageFont.truetype("arial.ttf", font_size)
draw = ImageDraw.Draw(img)
w, h = draw.textsize(text, font=font)
h += int(h*0.21)
draw.text(((width-w)/2, (height-h)/2), text=text, fill='white', font=font)
img.save('H.png')
gives:
The 0.21 factor usually works well for a large range of font sizes for the same font. E.g. just plugging in font size 30:
Use of anchors can help with this
import os
import string
from PIL import Image
from PIL import ImageFont, ImageDraw, ImageOps
width, height = 100, 100
text = 'H'
font_size = 100
os.makedirs('./{}'.format(text), exist_ok=True)
img = Image.new("L", (width, height), color=0) # "L": (8-bit pixels, black and white)
font = ImageFont.truetype("arial.ttf", font_size)
draw = ImageDraw.Draw(img)
draw.text(((width)/2, (height)/2), text=text, fill='white', font=font, anchor="mm", align='center')
img.save('H.png')
It works fine without w and h
P.S.: I've tested it, and it can work well with non-English characters also
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()
I'm dawing a simple pieslice with PIL
image = Image.new("RGBA", (256, 128), "#DDD")
draw = ImageDraw.Draw(image, image.mode)
draw.pieslice((0, 0 , 64, 64), 180, 270, fill="white)
del draw
image.save("file.png", "PNG")
As you can see the arc is not perfect. How I can make a perfect arc with PIL?
Draw on a larger image, then downscale:
N=4
image = Image.new("RGBA", (256*N, 128*N), "#DDD")
draw = ImageDraw.Draw(image, image.mode)
draw.pieslice((0, 0 , 64*N, 64*N), 180, 270, fill="white")
del draw
image = image.resize((256,128)) # using user3479125's correction
image.save("file2.png", "PNG")
Note for unutbu's answer:
Now the resize() returns a resized copy of an image. So it doesn't modify the original. So this should be:
N=4
image = Image.new("RGBA", (256*N, 128*N), "#DDD")
draw = ImageDraw.Draw(image, image.mode)
draw.pieslice((0, 0 , 64*N, 64*N), 180, 270, fill="white")
del draw
image = image.resize((256,128))
image.save("file2.png", "PNG")