Python PIL 長文本換行,二維碼,圖片合成

項目新需求,須要在後端進行圖片合成,合成方式爲「背景圖+二維碼+文本」node

from PIL import Image, ImageDraw, ImageFont
import qrcode
import pygame

backMode = {  # 背景圖屬性,個人背景圖上須要添加一個二維碼和多個文本框
    "back_url": "timep.png",  # 讀取圖片路徑
    "size": (550, 363),  # 圖片大小
    "QR": {  # 二維碼屬性
        "frame": (130, 130),  # 大小
        "position": (150, 800),  # 位置
    },
    "text": [{  # 文本框屬性
        "size": 25,  # 字號
        # "ttf": "FZXBSJW.TTF",  # 字體
        "ttf": "pfh.ttf",  # 字體
        "color": "",  # 顏色
        "position": (120, 140),  # 文字位置
        "frame": (300, 20),
    }, {
        "size": 25,
        "ttf": "pfh.ttf",
        "color": "",
        "position": (20, 80),
        "frame": (300, 20),
    }, {
        "size": 25,
        "ttf": "pfh.ttf",
        "color": "",
        "position": (20, 120),
        "frame": (300, 20),
    }, {
        "size": 25,
        "ttf": "pfh.ttf",
        "color": "",
        "position": (20, 160),
        "frame": (300, 20),
    }, ],
}


def make_QR(content, sizeW=0, sizeH=0):  # 建立二維碼
    qr = qrcode.QRCode(version=3, box_size=3, border=1, error_correction=qrcode.constants.ERROR_CORRECT_H)
    qr.add_data(content)
    qr.make(fit=True)
    img = qr.make_image()
    if sizeW == 0 and sizeH == 0:
        return img
    w, h = img.size
    if sizeW < w or sizeH < h:
        return None
    img = img.resize((sizeW, sizeH), Image.ANTIALIAS)
    return img


def com_pic(topimg, backimg, position):  # 合併圖片
    nodeA = position
    w, h = topimg.size
    nodeB = (position[0] + w, position[1] + h)
    backimg.paste(topimg, (nodeA[0], nodeA[1], nodeB[0], nodeB[1]))
    return backimg


def write_line(backimg, text, tmode):  # 給單個文本框填充數據
    myfont = ImageFont.truetype(tmode["ttf"], size=tmode["size"])
    draw = ImageDraw.Draw(backimg)
    tend = len(text)
    while True:
        text_size = draw.textsize(text[:tend], font=myfont)  # 文本圖層的尺寸
        # print(text_size)
        if text_size[0] <= tmode["frame"][0]:
            break
        else:
            tend -= 1  # 文本太長,調整文本長度
    draw.text((tmode["position"][0], tmode["position"][1]), text[:tend], font=myfont)

    return backimg, tend


def write_text(img, text, tmodeList):  # 寫文本
    tlist = text.split("\n")
    mnum = 0
    draw = ImageDraw.Draw(img)
    for t in tlist:
        tbegin = 0
        tend = len(t)
        while True:
            img, tend = write_line(img, t[tbegin:tend], tmodeList[mnum])
            mnum += 1
            if tbegin + tend == len(t) or mnum == len(tmodeList):
                break
            else:
                tbegin = tbegin + tend
                tend = len(t)
        if mnum == len(tmodeList):
            break
    return img


def make_pic(mode, text, url):
    img = Image.open(mode["back_url"])  # 讀取背景圖片
    QR_res = make_QR(url, mode["QR"]["frame"][0], mode["QR"]["frame"][1])  # 建立二維碼
    img = com_pic(QR_res, img, mode["QR"]["position"])  # 合成1
    img = write_text(img, text, mode["text"])  # 寫文本
    img.save('A.PNG', quality=100)


make_pic(backMode, "冷的月色\n鋪墊整場你禮貌", "http://m.luffycity.com")
exit()

 

 

文章來源  https://blog.csdn.net/weixin_41768265/article/details/80338439後端

相關文章
相關標籤/搜索