图片 flask json_基于flask的论坛签名档图片(上)

两周前,签名图(https://sig.dogcraft.top/img.jpg)的访问量自从有记录以来突破了一万次,为纪念访问量突破一万次,重写了大部分代码,并写了这篇搭建教程。

基本原理

原理并不复杂,浏览器向服务器请求图片时,浏览器会向服务器提供诸如IP地址、浏览器版本和访问时间等基本信息,服务器可以利用这些信息,生成相关的图片返回给浏览器,这样浏览器会收到一张写有用户端信息的独一无二的图片。如果这张图片的url被放在论坛的签名档里面,所有看到签名档的用户就会看到写有自己IP地址及相关信息的签名图。

7b86c444701fcaa173ecdafbb617dd71.png

签名图样式(IP地址是联通4G公网NAT出口地址,没什么意义)

实现过程

要实现这个过程并不复杂,我就采用最熟悉的flask框架来做这件事。

首先是获取浏览器的基本信息(IP地址、UA等),在flask框架下获取相关信息很容易:

from flask import (Flask,request)app = Flask(__name__)@app.route('/')def index():    dog_ip = request.remote_addr#获取IP地址    dog_ua = request.user_agent#获取浏览器UA    return [dog_ip,dog_ua]

获取了这两个基本信息之后,需要分别解析出浏览器的版本,所在的操作系统与ip地址所对应的物理地址。获取ip地址相关信息有很多方法,这里采用,采用https://ip.zxinc.org/api.php 的 ip 地址 api。调用方法如下:

import requestsdef get_ip_info(dogip):    canshu = {'ip': dogip, 'type': 'json'}    r = requests.get('https://ip.shanshan-business.com/api.php', params=canshu)    resd = (r.content.decode('utf8'))    res = json.loads(resd[1:])    if res['code'] != 0:        fu = [' ', ' ']        return fu    dog_location = res['data']['location']    dog_ip_fw = '{} - {}'.format(res['data']['ip']['start'], res['data']['ip']['end'])    return [dog_location, dog_ip_fw]
这个api会返回两个信息,分别是对应地理位置以及IP段范围。 另个关键点是解析解析浏览器的UA,即通过UA字段解析出客户端所用的浏览器、操作系统以及设备,这里采用的是user_agents这个库:
from user_agents import parsedog_ua = request.user_agentdog_uap = parse(str(dog_ua))dog_os = dog_uap.get_os()#获取操作系统信息dog_browser = dog_uap.get_browser()#获取浏览器信息dog_device = dog_uap.get_device()#获取设备信息

获取这两个信息之后就可以开始画出图形了。

首先应该准备一个适当大小的背景图片,用来充当签名图的基底,打开这个文件应该在初始化阶段,将文件内容读入到内存中,当浏览器请求签名图的时候再把这个图片在内存中复制一遍,在副本的基础上进行画图,使得整个过程可以可持续进行。

为了配合flask输出文件,需要把这个文件以字符串的形式在python中保存与处理,这需要io这个库

basdog = Image.open('bd.png', 'r')def dog_pic(ip, refer, ua):    [dog_location, dog_ip_fw] = get_ip_info(ip)#获取ip地址相关信息    dog_uap = parse(str(ua))    dog_os = dog_uap.get_os()    dog_browser = dog_uap.get_browser()    dog_device = dog_uap.get_device()    dog_num = get_number()    #生成相关文本    dog_text_1 = '只争朝夕,不负韶华。IP段 : {}'.format(dog_ip_fw)    dog_text_2 = 'IP地址: {}  {}'.format(ip, dog_location)    dog_text_3 = '{}'.format(refer)    dog_text_4 = '浏览器: {} OS: {} 设备: {}'.format(        dog_browser, dog_os, dog_device)    dog_text_5 = '已被访问{}次  北京时间:{}'.format(dog_num, time.ctime())    dog_text_6 = '为庆祝有记录以来访问量已经突破十万次,本签名图即将改版!'    # 开始画图了    image = basdog.copy()#复制基底片    #选择字体    font1 = ImageFont.truetype('/home/yu/.local/share/fonts/仿宋_GB2312.ttf', 14)    font2 = ImageFont.truetype('/home/yu/.local/share/fonts/仿宋_GB2312.ttf', 20)    draw = ImageDraw.Draw(image) #获取画笔    #文字写入对应位置    draw.text((10, 30), dog_text_1, font=font2, fill=(255, 0, 0))    draw.text((10, 70), dog_text_2, font=font2, fill=(0, 0, 0))    draw.text((10, 110), dog_text_3, font=font1, fill=rndColor2())    draw.text((10, 150), dog_text_4, font=font2, fill=rndColor2())    draw.text((10, 180), dog_text_5, font=font2, fill=rndColor2())    draw.text((10, 210), dog_text_6, font=font1, fill=rndColor2())    buf = io.BytesIO() # 字符串文件    image.save(buf, 'jpeg') #将画好的图片保存    image.close()    # 转化成flask的返回格式    buf_str = buf.getvalue()    response = app.make_response(buf_str)    response.headers['Content-Type'] = 'image/jpeg'    return response

剩下的部分内容(统计访问数量、部署方式以及完整代码)将在《基于flask的论坛签名档图片(下)》中完成。

如果想看一下效果,可以点下面的原文链接,签名图的地址已经放上去了。


Q:为什么不一次性写完?

A:……

之前提了好几周的封面图已经换好了0e027b0051560b30cee6df51ed341aa1.png

77ebfe74a651a6e2fa26acfdf914d0fa.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值