我们经常在一些网站上看到,在用户没有自定义头像的情况下,会给每个用户都生成一个头像,这让网站显得更美观,那这个是怎么实现的呢?在Flask中有一个插件,叫做Flask-avatars,专门提供头像解决方案。里面集成了各种头像解决方案。下面就来讲解一下。

一、安装

 

$ pip install flask-avatars

二、初始化

扩展需要以通常的方式初始化,然后才能使用:

from flask_avatars import Avatars

app = Flask(__name__)
avatars = Avatars(app)

三、配置

下面列出了可用的配置选项:

配置默认值描述
AVATARS_GRAVATAR_DEFAU LT 标识 Gravatar 默认头像类型
AVATARS_SAVE_PATH None 头像保存路径
AVATARS_SIZE_TUPLE (30, 60, 150) 头像大小元组,格式为 ,生成identicon头像时使用(small, medium, large)
AVATARS_IDENTICON_COLS 7 identicon 头像块的 cols
AVATARS_IDENTICON_ROWS 7 The ros of identicon avatar block
AVATARS_IDENTICON_BG None identicaon头像的背景色,通过RGB元组(例如 )使用随机颜色(125, 125, 125)` `). Default (``None
AVATARS_CROP_BASE_WIDT H 500 裁剪图像的显示宽度
AVATARS_CROP_INIT_POS (0, 0) cop box的初始位置,(x,y)的元组,默认为左上角
AVATARS_CROP_INIT_SIZE 没有任何 裁剪框的初始大小,默认为 AVATARS_SIZE_TUP LE[0]
AVATARS_CROP_MIN_SIZE 没有任何 裁剪框的最小尺寸,默认无限制
AVATARS_CROP_PREVIEW_S IZE 没有任何 预览框的大小,默认为 AVATARS_SIZE_TUP LE[1]
AVATARS_SERVE_LOCAL 错误的 从本地加载Jcrop资源(内置),默认使用CDN

四、头像

Flask-Avatarsavatars在模板上下文中提供了一个对象,您可以使用它来获取头像 URL。

1. Gravatar:

关于什么是Gravatar,这里引用了维基百科的一段介绍供读者参考:

在Gravatar上,用户可以用他们的电子邮件注册一个帐号,并且上传一个与之绑定的头像。许多流行的博客程序都支持Gravatar,包括WordpressTypecho等著名博客程序,当用户发布一个评论并填写了他的电子邮件地址时,博客程序会自动查找在Gravatar上是否有与之绑定的头像。如果有,则这个头像将会与评论一起显示出来。WordPress v2.5 开始原生地提供对Gravatar的支持。此外还有许多程序通过插件来支持Gravatar,例如论坛程序Discuz!

一个Gravatar头像可以使用高达512像素的图片,并且默认地以80*80的尺寸显示出来。如果上传的头像不是这个尺寸,Gravatar会对头像进行缩放。用户可以按照MPAA分级制度确定自己的头像级别,这样网站管理员可以在他们的站点上显示合适的头像。

为了防止用户的电子邮件地址遭到泄漏而收到大量垃圾邮件,Gravatar在传递用户的邮箱地址时采用的是通过MD5散列运算的邮件地址。

更多关于Gravatar的介绍请参考:https://zh.wikipedia.org/wiki/Gravatar

您可以使用avatars.gravatar()获取Gravatar提供的头像 URL ,传递电子邮件哈希:

<img src=" avatars.gravatar(email_hash) "/>

您可以像这样获得电子邮件哈希:

import hashlib

avatar_hash = hashlib.md5(my_email.lower().encode(\'utf-8\')).hexdigest()

2. Robohash

Robohash提供随机机器人头像,可以 avatars.robohash()用来获取头像网址,传递随机文本:

<img src=" avatars.robohash(some_text) "/>

 

3. Avatars.io 的社交媒体头像

Avatars.io让你可以使用你的社交媒体的头像(Twitter、Facebook 或 Instagram),你可以avatars.social_media()用来获取头像 URL,在目标社交媒体上传递你的用户名:

<img src=" avatars.social_media(username) "/>

默认使用 Twitter,使用platform更改它:

<img src=" avatars.social_media(username, platform=\'facebook\') "/>

4. 默认头像

Flask-Avatars 提供了三种尺寸的默认头像,用于 avatars.default()获取 URL:

<img src=" avatars.default() "/>

您可以使用size更改大小(sm和 之一l),例如:

<img src=" avatars.default(size=\'s\') "/>

5. 标识生成

Flask-Avatars 提供了一个Identicon生成identicon avatar的类,大部分代码基于randomavatar。首先,您需要设置配置变量AVATARS_SAVE_PATH来告诉 Flask-Avatars 保存生成的头像的路径。一般来说,我们会在创建用户记录的时候生成头像,所以生成头像最好的地方是在用户数据库模型类中:

class User(db.Model):
    avatar_s = db.Column(db.String(64))
    avatar_m = db.Column(db.String(64))
    avatar_l = db.Column(db.String(64))

    def __init__():
        generate_avatar()

    def generate_avatar(self):
        avatar = Identicon()
        filenames = avatar.generate(text=self.username)
        self.avatar_s = filenames[0]
        self.avatar_m = filenames[1]
        self.avatar_l = filenames[2]
        db.session.commit()

然后创建一个视图来提供头像图像,如下所示:

from flask import send_form_directory, current_app

@app.route(\'/avatars/<path:filename>\')
def get_avatar(filename):
    return send_from_directory(current_app.config[\'AVATARS_SAVE_PATH\'], filename)

 

五、头像裁剪

Flask-Avatars 基于Jcrop添加支持头像裁剪。

第 1 步:上传

第一步是让用户上传原始图像,因此我们需要在 HTML 中创建一个表单。上传.html

<form method="post" enctype="multipart/form-data">
    <input type="file" name="file"/>
    <input type="submit"/>
</form>

如果你使用 Flask-WTF,你可以创建一个这样的表单:

from flask_wtf.file import FileField, FileAllowed, FileRequired

class UploadAvatarForm(FlaskForm):
    image = FileField(\'Upload (<=3m)\', validators=[
        filerequired(),
        fileallowed([\'jpg\', \'png\'], \'the file format should be .jpg or .png.\')
    ])
    submit = submitfield()

当用户单击提交按钮时,我们使用以下命令保存文件 avatars.save_avatar()

app.config[\'AVATARS_SAVE_PATH\'] = os.path.join(basedir, \'avatars\')

# serve avatar image
@app.route(\'/avatars/<path:filename>\')
def get_avatar(filename):
    return send_from_directory(app.config[\'AVATARS_SAVE_PATH\'], filename)


@app.route(\'/\', methods=[\'GET\', \'POST\'])
def upload():
    if request.method == \'POST\':
        f = request.files.get(\'file\')
        raw_filename = avatars.save_avatar(f)
        session[\'raw_filename\'] = raw_filename  # you will need to store this filename in database in reality
        return redirect(url_for(\'crop\'))
    return render_template(\'upload.html\')

第 2 步:裁剪

现在我们创建一个裁剪路由来渲染裁剪页面:

@app.route(\'/crop\', methods=[\'GET\', \'POST\'])
def crop():
    if request.method == \'POST\':
        ...
    return render_template(\'crop.html\')

这是crop.html的内容:

<head>
    <meta charset="utf-8">
    <title>Flask-Avatars Demo</title>
     avatars.jcrop_css()   <!-- include jcrop css -->
    &lt;style&gt;
        <!-- some css to make a better preview window -->
    &lt;/style&gt;
</head>
<body>
    <h1>Step 2: Crop</h1>
     avatars.crop_box(\'get_avatar\', session[\'raw_filename\'])   <!-- crop window -->
     avatars.preview_box(\'get_avatar\', session[\'raw_filename\'])   <!-- preview widow -->
    <form method="post">
        <input type="hidden" id="x" name="x"/>
        <input type="hidden" id="y" name="y"/>
        <input type="hidden" id="w" name="w"/>
        <input type="hidden" id="h" name="h"/>
        <input type="submit" value="crop!"/>
    </form>
     avatars.jcrop_js()   <!-- include jcrop javascript -->
     avatars.init_jcrop()   <!-- init jcrop -->
</body>

注意我们创建的用于保存裁剪位置数据的表单,四个输入的名称和 id 必须是xywh

如果你使用 Flask-WTF/WTForms,你可以像这样创建一个表单类:

class CropAvatarForm(FlaskForm):
    x = HiddenField()
    y = HiddenField()
    w = HiddenField()
    h = HiddenField()
    submit = SubmitField(\'Crop\')

第 3 步:保存

当用户点击裁剪按钮时,我们可以处理屏幕背后的真实裁剪工作:

@app.route(\'/crop\', methods=[\'GET\', \'POST\'])
def crop():
    if request.method == \'POST\':
        x = request.form.get(\'x\')
        y = request.form.get(\'y\')
        w = request.form.get(\'w\')
        h = request.form.get(\'h\')
        filenames = avatars.crop_avatar(session[\'raw_filename\'], x, y, w, h)
        url_s = url_for(\'get_avatar\', filename=filenames[0])
        url_m = url_for(\'get_avatar\', filename=filenames[1])
        url_l = url_for(\'get_avatar\', filename=filenames[2])
        return render_template(\'done.html\', url_s=url_s, url_m=url_m, url_l=url_l)
    return render_template(\'crop.html\')

avatars.crop_avatar()在元组中返回裁剪文件名 ,您可能需要将其存储在数据库中。(filename_s, filename_m, filename_l)

六、示例应用

目前,我们有三个例子:

  • 示例/基础
  • 示例/标识
  • 例子/作物

您可以通过以下方式运行示例应用程序:

$ git clone https://github.com/greyli/flask-avatars.git
$ cd flask-avatars/examples
$ pip install flask flask-avatars
$ cd basic
$ flask run