FreeShare

Ví dụ về service xử lý ảnh bằng python3

Chủ nhật, 18/02/2024
image
Đầu tiên cần cài đặt python 3.9 và pip3 vào máy tính kiểm tra cài đặt bằng các lệnh Tạo folder dự án và tạo 2 file index.py và requirements.txt. nội dung file rrequirements.txt có nội dung như sau cài đặt thư việ với dòng lệnh Tạo api với Flash với code Hàm xử lý […]

Đầu tiên cần cài đặt python 3.9 và pip3 vào máy tính kiểm tra cài đặt bằng các lệnh

python3 --version
pip3 --version

Tạo folder dự án và tạo 2 file index.py và requirements.txt. nội dung file rrequirements.txt có nội dung như sau

numpy==1.23.0
opencv-python==4.6.0.66
Pillow==9.2.0
qrcode==7.3.1
flask==2.1.2
python-dotenv==0.20.0
Flask-Cors==3.0.10

cài đặt thư việ với dòng lệnh

pip3 install -r requirements.txt

Tạo api với Flash với code

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from dotenv import load_dotenv
from flask import Flask, send_from_directory
from flask_cors import CORS

app = Flask(__name__, static_url_path='')
load_dotenv()
CORS(app)

if __name__ == '__main__':
    app.run(port=8000)

Hàm xử lý ảnh từ ảnh hình vuông resize và border thành tròn

def mask_circle_transparent(pil_img, blur_radius, offset=0):
    try:
        offset = blur_radius * 2 + offset
        mask = Image.new("L", pil_img.size, 0)
        draw = ImageDraw.Draw(mask)
        draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
        mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))
        result = pil_img.copy()
        result.putalpha(mask)
        return result
    except Exception as e:
        print(e)
        pass

Hàm xử lý crop ảnh ở đây crop ảnh theo min size hoặc max size

def crop_center(pil_img, crop_width, crop_height):
    img_width, img_height = pil_img.size
    return pil_img.crop(((img_width - crop_width) // 2,
                         (img_height - crop_height) // 2,
                         (img_width + crop_width) // 2,
                         (img_height + crop_height) // 2))


def crop_max_square(pil_img):
    return crop_center(pil_img, max(pil_img.size), max(pil_img.size))


def crop_min_square(pil_img):
    return crop_center(pil_img, min(pil_img.size), min(pil_img.size))

Hàm generate qrcode

def gen_qrcode(qrText=''):
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_H,
        box_size=10,
        border=1,
    )
    qr.add_data(qrText)
    qr.make(fit=True)
    img = qr.make_image()
    small_img = img.resize((350, 350), Image.ANTIALIAS)
    small_img.save("./cards/qrcode.png")

Hàm vẽ ảnh và lưu vào folder

def drawImage(id, name, email, avatar):
    try:
        rand = random.randint(1, 5)
        main_color = getMainColor(rand)

        # xử lý resize và lưu lại ảnh mới, dùng trong trường hợp kích thước ảnh khác nhau
        im = Image.open('./avatar/' + avatar)
        im_square = crop_min_square(im).resize((241, 241), Image.LANCZOS)
        im_thumb = mask_circle_transparent(im_square, 2)
        im_thumb.save('./avatar/avatar_resize_default.png')

        back_ground = './cards/card-demo.jpeg'

        qr_text = 'Test-' + id
        gen_qrcode(qr_text)
        background = Image.open(back_ground, 'r')

        avatar = Image.open('./avatar/avatar_resize_default.png', 'r')
        qrcode = Image.open('./cards/qrcode.png', 'r')

        text_img = background.copy()

        text_img.paste(avatar, (392, 270))
        text_img.paste(qrcode, (350, 610))

        fntBold = ImageFont.truetype('./fonts/Roboto-Bold.ttf', 52, encoding="utf-8")
        fntBlack = ImageFont.truetype('./fonts/Roboto-Bold.ttf', 75, encoding="utf-8")
        fntEmail = ImageFont.truetype('./fonts/Roboto-Bold.ttf', 32, encoding="utf-8")
        draw = ImageDraw.Draw(text_img)

        name_padding = 280
        draw.text((name_padding, 100), name, font=fntBlack, fill=main_color)

        id_padding = 450
        draw.text((id_padding, 200), "ID-" + id, font=fntBold, fill=main_color)

        f_email = format_email(email)
        f_email_padding = 400
        draw.text((f_email_padding, 550), f_email, font=fntEmail, fill=main_color)

        text_img.save('./test-image/' + id + '.png', format="png")

    except Exception as e:
        print(e)
        pass

Viết api

@app.route('/test-image/<path>')
def check_image(path):
    if '.png' not in path:
        return 'Invalid url'
    check = os.path.exists('./test-image/' + path)
    path = path.lower()
    name = path.replace('.png', '')
    if check:
        return send_from_directory('test-image', path)
    else:
        result_path = process_image(name)
        if result_path == 'ok':
            return send_from_directory('test-image', path)
        return result_path
    return 'Error'

chạy dự án với lệnh: python3 index.py

bạn có thể tham khảo full code mẫu tại đây