Tạo hiệu ứng instagram card bằng thư viện pillow trên python (P1)


Chào mọi người,
Dạo gần đây tôi cảm thấy rất thích webapp có tên là Quahat-Inscard - dùng để tạo hiệu ứng cho ảnh Instagram. Vì vậy hôm nay tôi hướng dẫn các bạn làm thế nào để tạo một hình ảnh tương tự bằng ngôn ngữ lập trình python.

English version here.

Việc tạo những hình ảnh có hiệu ứng đẹp nhanh chóng sẽ rất có ích cho những người làm các cuộc thi về hình ảnh, họ chỉ cần đưa ảnh đầu vào. Việc thiết kế sẽ trở nên đơn giản hơn.

Dự án này bao gồm hai phần chính:
  1. Đoạn mã python để xử lí ảnh
  2. Hệ thống sever để get API từ Instagram
Hôm nay mình sẽ viết về việc làm thế nào để xử lí ảnh trên python. Tiến hành thôi!

Phân tích hình ảnh được tạo ra chúng ta sẽ thấy có 5 lớp ảnh: Background, shadow, card, avatar và cuối cùng là thông tin tài khoản. Mình muốn chỉ sử dụng duy nhất thư viên PIL để thực hiện nó.Trước tiên hãy tạo dự án và cài đặt thư viện pillow trên cửa sổ terminal.

>> pip install pillow

1. Thêm thư viện

from PIL import Image, ImageDraw
from PIL import ImageFilter, ImageFont

Khai báo thư viện Image để có thể trích xuất các thông tin từ hình ảnh và xử lí hình ảnh. Thư viện ImageDraw, ImageFont cho phần thông tin, ImageFilter cho các hiệu ứng.

2. Tải hình ảnh từ thư mục

Tải hình ảnh mà các bạn muốn thêm hiệu ứng từ instagram và bỏ chúng vào thư mục chính của project. Nhớ đổi tên hình ảnh thành "image.jpg" sau đó thực hiện lệnh nhập hình ảnh và trích xuất kích thước.

image = Image.open('image.jpg')
h = image.size[0]
w = image.size[1]

Nếu không phải hình ảnh từ instagram, chúng ta chọn những hình ảnh có kích thước vuông và thay thế bằng đoạn code sau.

your_image = Image.open('image.jpg')
image = your_image.resize((1080, 1080), Image.ANTIALIAS)
h = image.size[0]
w = image.size[1]

Lưu ý: Hãy chắc chắn là hình ảnh sử dụng có thuộc tính height ≤ width

3. Tạo ảnh nền

background = image.crop((0, int(int(w-h)/2), int(h), int(int(w)-int(w-h)/2)))

Ảnh nền sẽ có kích thước là 1080x1080. Tôi đã tạo được ảnh nền như phía dưới.



Kích thước của ảnh nền là kích thước chuẩn cho các thiết kế khác. Sẽ xuất hiện vài lỗi nếu chúng ta sử dụng hình tỷ lệ nằm ngang (ví dụ: 16:9).Chúng ta có thể khắc phục điều này bằng việc thêm các điều kiện xử lí khác nhau cho ảnh đầu vào, tuy nhiên ở đây tôi chỉ viết cho ảnh dọc.

5. Tạo thẻ

#card modulecard = image.crop((270, 50, 860, 1050))

Sau đó tôi sẽ tạo layer thứ 2 - thẻ instagram.

4. Tạo bóng mờ

#shadow modulesh1 = background
sh2 = Image.open('./materials/shadow.jpg')
sh3 = Image.open('./materials/solid_shadow.jpg')
mask_sh = Image.new("L", sh2.size, 0)
draw_sh = ImageDraw.Draw(mask_sh)
mask_sh = sh3.resize(sh2.size).convert('L')
back_sh = sh1.copy()
back_sh.paste(sh2, (270, 100), mask_sh)
sh = back_sh.filter(ImageFilter.GaussianBlur(radius=10))

Trước tiên, chúng ta phải tải xuống các file nằm thư mục có tên là "materials" và đặt chúng vào thư mục có tên là materials do các bạn tạo ra. Bạn có thể tải nó phía dưới.



6. Chèn thẻ

Chèn thẻ vào background đã có sẵn bóng mờ.

#insert cardbackground_shadow = sh
is1 = background_shadow.resize((1200, 1200), Image.ANTIALIAS)
is2 = card
is3 = Image.open('./materials/solid.jpg')
mask_is = Image.new("L", is2.size, 0)
draw_is = ImageDraw.Draw(mask_is)
mask_is = is3.resize(is2.size).convert('L')
back_is = is1.copy()
back_is.paste(is2, (298, 115), mask_is)

Xem kết quả thôi :)


7. Chèn avatar

Copy hình avatar mà các bạn tải xuống từ instagram và bỏ vào thư mục materials, hình ảnh sẽ có kích thước là 150x150 pixel. Nếu muốn hình khác thì các bạn phải chuyển nó về dạng vuông. Chúng ta có một đoạn code chuyển kích thước hình avatar về 100x100 pixel, đừng quên tải bộ materials phía trên.

#insert_avatarav1 = back_is
av2_1 = Image.open('./materials/avatar.jpg')
av2 = av2_1.resize((100, 100), Image.ANTIALIAS)
av3 = Image.open('./materials/solid_avatar.jpg')
mask_av = Image.new("L", av2.size, 0)
draw_av = ImageDraw.Draw(mask_av)
mask_av = av3.resize(av2.size).convert('L')
av = av1.copy()
av.paste(av2, (345, 170), mask_av)

8. Chèn thông tin

#texttext = av
draw_text = ImageDraw.Draw(text)
font_01 = ImageFont.truetype(r'.\fonts/TCCEB.ttf', 28)
font_02 = ImageFont.truetype(r'.\fonts/TCCEB.ttf', 40)
draw_text.text((530, 160),"phongcanon",(255,255,255),font=font_01)
draw_text.text((502, 220),"34",(255,255,255),font=font_02)
draw_text.text((615, 220),"325",(255,255,255),font=font_02)
draw_text.text((775, 220),"56",(255,255,255),font=font_02)

Chúng ta có thể sửa nó, "phongcanon" là tên tài khoản, "34"số lượng bài đăng, "325" số người đang theo dõi và "56" là số người theo dõi mình.

9. Thêm giao diện

#insert theme
in1 = text
in2 = Image.open('./materials/white.jpg')
in3 = Image.open('./materials/info.jpg')
mask_info = Image.new("L", in2.size, 0)
draw_in = ImageDraw.Draw(mask_info)
mask_info = in3.resize(in2.size).convert('L')
info = in1.copy()
info.paste(in2, (298, 115), mask_info)
info.save('result.jpg', quality=95)

Chúng ta đã hoàn thành instagram card rồi.
Project này sẽ được phát triển thêm chức năng lấy API từ Instagram sau này. Cuối cùng, đây là thành quả của chúng ta, hình ảnh sẽ trả về trong thư mục chính của project.


Hãy chia sẻ bài viết nếu các bạn thích nha. Chúc mọi người thành công.