千家信息网

如何用Python给二维码图片添加提示文字

发表于:2024-12-12 作者:千家信息网编辑
千家信息网最后更新 2024年12月12日,这篇文章主要讲解了"如何用Python给二维码图片添加提示文字",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"如何用Python给二维码图片添加提示文字
千家信息网最后更新 2024年12月12日如何用Python给二维码图片添加提示文字

这篇文章主要讲解了"如何用Python给二维码图片添加提示文字",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"如何用Python给二维码图片添加提示文字"吧!

需求:

判断当前浏览器是否为微信,是的话挑起微信支付,不是的话,显示二维码图片并提示用户到微信中打开

代码实现:

1. 判断是否微信

# toolbox.pyfrom typing import Any  class UserAgent:    def __init__(self, user_agent: str = '', request: Any = None):        if request is not None:            try:                user_agent = request.headers.get('user-agent', '')  # For Sanic            except AttributeError:                user_agent = request.META.get('HTTP_USER_AGENT', '')  # Django        self.user_agent = user_agent     @property    def is_alipay(self) -> bool:        return "AlipayClient/" in self.user_agent     @property    def is_wechat(self) -> bool:        return "MicroMessenger/" in self.user_agent     @property    def is_qq(self) -> bool:        return " QQ/" in self.user_agent     @property    def scan_type(self) -> str:        if self.is_wechat or self.is_qq:            return "wechat"        if self.is_alipay:            return "alipay"        return "unknown"

2. 给图片加文字

# image_text.py"""给图片(如二维码)添上文字Usage::    >>> from xxx import deco_image    >>> deco_image(image_path, text)  # 替换旧图片    >>> deco_image(image_path, text, new_path, color='red')  # 保留旧图片并指定文字颜色"""from pathlib import Pathfrom typing import Optional, Tuple, Union from PIL import Image, ImageDraw, ImageFont  # pip install pillow TIP = "请用微信扫码支付或分享到微信中打开"  # 获取图片宽度def get_img_width(fname) -> int:    return Image.open(fname).size[0]  # 获取图片高度def get_img_height(fname) -> int:    return Image.open(fname).size[1]  # 给图片加文字# 生成blank_img空白图片,加上文字之后生成新图片或覆盖旧图, 宽度为origin_img原始图片的宽度 MARGIN_LEFT, MARGIN_TOP = 50, 15FONT_SIZE = 22FONT_COLOR = "red"  def gen_text_img(    origin_img: Union[Path, str],    text: str,    img_path=None,    color=FONT_COLOR,    font_size: int = FONT_SIZE,    margin_left: int = MARGIN_LEFT,    margin_top: int = MARGIN_TOP,    blank_img=None,    font_path: Optional[str] = None,    show_img: bool = False,) -> Union[Path, str]:    width = get_img_width(origin_img)    if blank_img is None:        blank_img = Path(f"/tmp/blank-{width}.png")    elif isinstance(blank_img, str):        blank_img = Path(blank_img)    if not blank_img.exists():        Image.new("RGB", (width, 70), (255, 255, 255)).save(blank_img)    im = Image.open(blank_img)    draw = ImageDraw.Draw(im)    if font_path is None:        # font_path = r"C:WindowsFontssimsun.ttc"        # font_path = "/System/Library/Fonts/Supplemental/Songti.ttc"        font_path = "/usr/share/fonts/truetype/windows-font/Songti.ttc"    fnt = ImageFont.truetype(font_path, font_size)    draw.text((margin_left, margin_top), text, fill=color, font=fnt)    if img_path is None:        img_path = Path(origin_img)        img_path = img_path.with_name(f"{img_path.stem}-{len(text)}{img_path.suffix}")    im.save(img_path)    if show_img:        im.show()    return img_path  # 拼接图片,把上面生成的文字图片拼接到原图上面# 生成一张宽度一致,高度为两张图片之和的空白长图# 分别打开图片进行粘贴到空白长图里面 def join_imgs(text_img, origin_img, new_path=None) -> None:    w = get_img_width(text_img)    fh = get_img_height(text_img)    oh = get_img_height(origin_img)     blank_long_img = Image.new("RGBA", (w, fh + oh))  # 空白长图     font_img = Image.open(text_img).resize((w, fh), Image.ANTIALIAS)    blank_long_img.paste(font_img, (0, 0))     img1 = Image.open(origin_img).resize((w, oh), Image.ANTIALIAS)    blank_long_img.paste(img1, (0, fh))    if new_path is None:        new_path = origin_img    blank_long_img.save(new_path)    blank_long_img.show()  def deco_image(    fpath: Union[Path, str],  # 图片路径    text: str = TIP,  # 要添加的文字    new_path: Union[Path, str, None] = None,  # 新图片要保存的路径(默认覆盖原图)    color: Union[str, Tuple[int, int, int]] = FONT_COLOR,  # 文字颜色    font_size: int = FONT_SIZE,  # 文字高度    margin_left: int = MARGIN_LEFT,    margin_top: int = MARGIN_TOP,) -> None:    text_img = gen_text_img(        fpath,        text,        color=color,        font_size=font_size,        margin_left=margin_left,        margin_top=margin_top,    )    join_imgs(text_img, fpath)

3. 如果系统缺字体,那么需要去下载

sudo mkdir /usr/share/fonts/truetype/windows-fontsudo chmod 777 /usr/share/fonts/truetype/windows-fontcd /usr/share/fonts/truetype/windows-fontwget https://gitee.com/waketzheng/carstino/attach_files/703450/download/Songti.ttc  # 该文件比较大,有66.9MB

4. 调起支付或生成图片

from pathlib import Pathfrom hashlib import md5 import qrcode  # pip install qrcodefrom sanic import Blueprintfrom sanic.log import loggerfrom sanic.request import Requestfrom sanic.response import json from .models import Orderfrom .image_text import deco_imagefrom .toolbox import UserAgentfrom .utils import async_http_post, get_hostfrom .consts import URL_PREFIX, WX_PAY_URL  bp = Blueprint("epay", url_prefix=URL_PREFIX) async def get_qf_mch(community):    pass  @bp.route("/pay-link", methods=["POST"])async def pay_link(request: Request):    requires, data = ["bills", "total", "next"], request.json    logger.info(f"{request.url = } ;  {request.json = }")    # 已经1分钟内生成过对应订单的,直接去支付    content = request.body + f"{datetime.now():%y%m%d%H%M%S}".encode()    body = md5(content).hexdigest()    if not (order := await Order.filter(body=body).first()):        order = await new_pay_order(origin, data, request, body)    mchid, mch_name = await get_qf_mch(order.community)    if mchid:        host = get_host(request.headers)        if not UserAgent(request=request).is_wechat:            # 故判断当前是否在微信里,如果不是就直接生成二维码            frontend_url = data["next"]            fpath = "payit/" + md5(frontend_url.encode()).hexdigest() + ".png"            if not (p := BASE_DIR / "media" / fpath).parent.exists():                p.parent.mkdir(parents=True)            qrcode.make(frontend_url).save(p)            deco_image(p)            img_url = host + URL_PREFIX + "/media/" + fpath            return json({"payUrl": img_url})        return json(qf_pay_it(mchid, mch_name, order, host=host))    url = WX_PAY_URL    if not (request_data := order.post_data).get("mch"):        request_data.update(mch=1)  # 未配置支付的,先用1    res = await async_http_post(url, request_data)    try:        res_json = res.json()    except Exception as e:        logger.error(f"{e = }; {url = }; {order.post_data=}; {res.content = }")    return json(res_json)

    感谢各位的阅读,以上就是"如何用Python给二维码图片添加提示文字"的内容了,经过本文的学习后,相信大家对如何用Python给二维码图片添加提示文字这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

    0