We will build a logic to create some random captcha image using python with the help of pillow package.
For more detailed reference about pillow check this.
install this package using this command
pip install pillow
To learn more about virtual environment
Create new image
this piece of code will create a white image with 90X60 and saved a blank_image.png
from PIL import Image
img = Image.new('RGB', (90, 60), color = 'white')
img.save('blank_image.png')
Draw text on image
now we created a image and saved it, lets add some text to it
from PIL import Image, ImageDraw
draw = ImageDraw.Draw(img)
draw.text((20,20), "Hello", fill=(38, 38, 38))
img.save('blank_image.png')
Hello
is written in img object at poin 10X10
Draw lines
Let draw some line on the image
draw.line((40,30, 150,300), fill=120, width=1)
draw.line((20,30, 30,20), fill=88, width=2)
fill is the color and you set the width size,
(40,30) is the starting point for line 1 and ends at (150,300).
You can notice that the end point is larger than the image size, it will be omitted.
Same as line 1, line 2 starts at (20,30) and ends in (30,20)
Draw points
Let add some more stuff
pass points as python tuples of tuples to draw points in the image
draw.point(((30, 40), (10, 20), (14, 25), (35, 10), (14, 28), (17, 25)), fill="black")
this one will throws the dot points in the image at the given XY coordinates.
Generate the captcha string
This same logic is used in Url Shortener, you can check it here
Build Url Shortener API In Django - Redis
random_string function generate a random string of length 5, you can adjust it.
import string, random
# generate thr random captcha string
def random_string():
# hash length
N = 5
s = string.ascii_uppercase + string.ascii_lowercase + string.digits
# generate a random string of length 5
random_string = ''.join(random.choices(s, k=N))
return random_string
Python lambda function
what is lambda?
Is a special function with one line, and with one expression. It can get multiple arguments.
# Normal funtion
def square(a):
return a*a
square(5) ---> 25
# lambda funtion
square = lambda a: a*a
square(5) ---> 25
lambda function to get the random location in the image
# lambda function - used to pick a random loaction in image
getit = lambda : (random.randrange(5, 85),random.randrange(5, 55))
this will spite out the random value between 5 and 84,
Note: 85 not taken
random.randrange(5, 85)
values for colors which will be randomly picked
# pick a random colors for points
colors = ["black","red","blue","green",(64, 107, 76),(0, 87, 128),(0, 3, 82)]
fill_color = [120,145,130,89,58,50,75,86,98,176,]
# pick a random colors for lines
fill_color = [(64, 107, 76),(0, 87, 128),(0, 3, 82),(191, 0, 255),(72, 189, 0),(189, 107, 0),(189, 41, 0)]
To get a random value from list, this will get a random color value one
random.choice(colors)
Full logic to generate the captcha image
from PIL import Image, ImageDraw, ImageFont
import string, random
# generate thr random captcha string
def random_string():
# hash length
N = 5
s = string.ascii_uppercase + string.ascii_lowercase + string.digits
# generate a random string of length 5
random_string = ''.join(random.choices(s, k=N))
return random_string
# lambda function - used to pick a random loaction in image
getit = lambda : (random.randrange(5, 85),random.randrange(5, 55))
# pick a random colors for points
colors = ["black","red","blue","green",(64, 107, 76),(0, 87, 128),(0, 3, 82)]
# fill_color = [120,145,130,89,58,50,75,86,98,176,]
# pick a random colors for lines
fill_color = [(64, 107, 76),(0, 87, 128),(0, 3, 82),(191, 0, 255),(72, 189, 0),(189, 107, 0),(189, 41, 0)]
# generate thr random captcha string
def random_string():
# hash length
N = 5
s = string.ascii_uppercase + string.ascii_lowercase + string.digits
# generate a random string of length 5
random_string = ''.join(random.choices(s, k=N))
return random_string
# generate the captcha image
def gen_captcha_img():
# create a img object
img = Image.new('RGB', (90, 60), color="white")
draw = ImageDraw.Draw(img)
# get the random string
captcha_str = random_string()
# get the text color
text_colors = random.choice(colors)
font_name = "fonts/SansitaSwashed-VariableFont_wght.ttf"
font = ImageFont.truetype(font_name, 18)
draw.text((20,20), captcha_str, fill=text_colors, font=font)
# draw some random lines
for i in range(5,random.randrange(6, 10)):
draw.line((getit(), getit()), fill=random.choice(fill_color), width=random.randrange(1,3))
# draw some random points
for i in range(10,random.randrange(11, 20)):
draw.point((getit(), getit(), getit(), getit(), getit(), getit(), getit(), getit(), getit(), getit()), fill=random.choice(colors))
# save image in captcha_img directory
img.save("captcha_img/"+ captcha_str +".png")
return True
**WE MADE IT** 🥳🥳🥳
You will notice the code for i in range(5,random.randrange(6, 10)):
which is used to randomise the line and points in each new image.
font used in this is from google fonts
https://fonts.google.com/specimen/Sansita+Swashed
Note: To validate the value(Backend) in the string you can store the string in the session or you can use your own way.
To generate more detailed image used some small images with different shapes in it and throws it randomly.
Top comments (0)