• Python PIL 长文本换行,二维码,图片合成


    项目新需求,需要在后端进行图片合成,合成方式为“背景图+二维码+文本”

    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("
    ")
        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, "冷的月色
    铺垫整场你礼貌", "http://m.luffycity.com")
    exit()

    文章来源  https://blog.csdn.net/weixin_41768265/article/details/80338439

  • 相关阅读:
    曾今的代码系列——获取当天最大流水号存储过程
    曾今的代码系列——生产者消费者模式
    利用Microsoft.VisualBasic中TextFieldParser解析器把CSV格式倒入数据库
    曾今的代码系列——自己的分页控件+存储过程实现分页
    ASP.NET那点不为人知的事(四)
    SharePoint下用C#代码上传文档至文档库的子文件夹中
    Entity Framework 4 in Action读书笔记——第四章:使用LINQ to Entities查询:使用函数
    Entity Framework 4 in Action读书笔记——第四章:使用LINQ to Entities查询:预先加载和延迟加载
    这几天Colorbox让我寝食难安
    使用ASP.NET MVC3+EF+Jquery制作文字直播系统(四)——完成篇
  • 原文地址:https://www.cnblogs.com/win-lin08/p/9284501.html
Copyright © 2020-2023  润新知