我们经常在一些网站上看到,在用户没有自定义头像的情况下,会给每个用户都生成一个头像,这让网站显得更美观,那这个是怎么实现的呢?在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) }}"/>
roboash 演示

 

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') }}"/>
avatars.io 演示

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