用Flask处理图片非常容易,这一篇学习一下图片的上传、下载及展示。还是以实例代码演示为主。
首先,实现一个简单的上传(过程中未做任何处理,只是为了演示)
点击选择图片,输入李四:
HTML代码:
Title
点击提交信息后,通过 http://localhost:5000/up_photo,传递到后台对应的路由处理,查看控制台:
后台接收的路由代码:
basedir = os.path.abspath(os.path.dirname(__file__))
@app.route('/up_photo', methods=['post'])
def up_photo():
img = request.files.get('txt_photo')
username = request.form.get("name")
path = basedir+"/static/photo/"
file_path = path+img.filename
img.save(file_path)
print '上传头像成功,上传的用户是:'+username
return render_template('index.html')
此时,我们查看static/photo时,已经可以看到我们点击上传的图片了。
以上是最简单的一个文件上传示例,我们实际使用中基本不可能这样去写,通常会做一些处理。例如:上传后做图片名称唯一性的处理、限制上传文件的类型、无论上传成功或者失败,都去做一些返回提示等等。
限制上传文件类型,例如,我们希望用户上传的文件为图片类型
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'JPG', 'PNG', 'gif', 'GIF'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
上面的代码片段通过截取上传文件的后缀名,判断是否是属于我们期望用户上传的类型。
更改上传图片名称,防止重名
这里我们使用日期加随机数生成图片名,做一个生成字符串的工具类
#-*-coding:utf-8-*-
import datetime
import random
class Pic_str:
def create_uuid(self): #生成唯一的图片的名称字符串,防止图片显示时的重名问题
nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S"); # 生成当前时间
randomNum = random.randint(0, 100); # 生成的随机整数n,其中0<=n<=100
if randomNum <= 10:
randomNum = str(0) + str(randomNum);
uniqueNum = str(nowTime) + str(randomNum);
return uniqueNum;
当我们点击图片上传,选择图片点击提交后,页面返回提示信息如下图:
此时看我们工程下的upload文件夹,唯一名称的图片已经上传成功
图片的下载
@app.route('/download/', methods=['GET'])
def download(filename):
if request.method == "GET":
if os.path.isfile(os.path.join('upload', filename)):
return send_from_directory('upload', filename, as_attachment=True)
pass
图片的展示
# show photo
@app.route('/show/', methods=['GET'])
def show_photo(filename):
file_dir = os.path.join(basedir, app.config['UPLOAD_FOLDER'])
if request.method == 'GET':
if filename is None:
pass
else:
image_data = open(os.path.join(file_dir, '%s' % filename), "rb").read()
response = make_response(image_data)
response.headers['Content-Type'] = 'image/png'
return response
else:
pass
完整示例代码
#encoding:utf-8
#!/usr/bin/env python
from werkzeug.utils import secure_filename
from flask import Flask, render_template, jsonify, request, make_response, send_from_directory, abort
import time
import os
from strUtil import Pic_str
import base64
app = Flask(__name__)
UPLOAD_FOLDER = 'upload'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
basedir = os.path.abspath(os.path.dirname(__file__))
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'JPG', 'PNG', 'gif', 'GIF'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
@app.route('/upload')
def upload_test():
return render_template('up.html')
# 上传文件
@app.route('/up_photo', methods=['POST'], strict_slashes=False)
def api_upload():
file_dir = os.path.join(basedir, app.config['UPLOAD_FOLDER'])
if not os.path.exists(file_dir):
os.makedirs(file_dir)
f = request.files['photo']
if f and allowed_file(f.filename):
fname = secure_filename(f.filename)
print fname
ext = fname.rsplit('.', 1)[1]
new_filename = Pic_str().create_uuid() + '.' + ext
f.save(os.path.join(file_dir, new_filename))
return jsonify({"success": 0, "msg": "上传成功"})
else:
return jsonify({"error": 1001, "msg": "上传失败"})
@app.route('/download/', methods=['GET'])
def download(filename):
if request.method == "GET":
if os.path.isfile(os.path.join('upload', filename)):
return send_from_directory('upload', filename, as_attachment=True)
pass
# show photo
@app.route('/show/', methods=['GET'])
def show_photo(filename):
file_dir = os.path.join(basedir, app.config['UPLOAD_FOLDER'])
if request.method == 'GET':
if filename is None:
pass
else:
image_data = open(os.path.join(file_dir, '%s' % filename), "rb").read()
response = make_response(image_data)
response.headers['Content-Type'] = 'image/png'
return response
else:
pass
if __name__ == '__main__':
app.run(debug=True)
基本示例就以上这些了!