用flask处理图片非常容易,这一篇学习一下图片的上传、下载及展示。还是以实例代码演示为主。
首先,实现一个简单的上传(过程中未做任何处理,只是为了演示)
点击选择图片,输入李四:
html代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<!doctype html>
<html lang = "en" >
<head>
<meta charset = "utf-8" >
<title>title< / title>
< / head>
<body>
<div>
<form method = "post" action = "http://localhost:5000/up_photo" enctype = "multipart/form-data" >
< input type = "file" size = "30" name = "photo" / >
<br>
< input type = "text" class = "txt_input" name = "name" style = "margin-top:15px;" / >
< input type = "submit" value = "提交信息" class = "button-new" style = "margin-top:15px;" / >
< / form>
< / div>
< / body>
< / html>
|
点击提交信息后,通过 http://localhost:5000/up_photo,传递到后台对应的路由处理,查看控制台:
后台接收的路由代码:
1
2
3
4
5
6
7
8
9
10
11
|
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时,已经可以看到我们点击上传的图片了。
以上是最简单的一个文件上传示例,我们实际使用中基本不可能这样去写,通常会做一些处理。例如:上传后做图片名称唯一性的处理、限制上传文件的类型、无论上传成功或者失败,都去做一些返回提示等等。
限制上传文件类型,例如,我们希望用户上传的文件为图片类型
1
2
3
4
|
allowed_extensions = set ([ 'png' , 'jpg' , 'jpg' , 'png' , 'gif' , 'gif' ])
def allowed_file(filename):
return '.' in filename and filename.rsplit( '.' , 1 )[ 1 ] in allowed_extensions
|
上面的代码片段通过截取上传文件的后缀名,判断是否是属于我们期望用户上传的类型。
更改上传图片名称,防止重名
这里我们使用日期加随机数生成图片名,做一个生成字符串的工具类
1
2
3
4
5
6
7
8
9
10
11
|
#-*-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文件夹,唯一名称的图片已经上传成功
图片的下载
1
2
3
4
5
6
|
@app .route( '/download/<string:filename>' , 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
|
图片的展示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# show photo
@app .route( '/show/<string:filename>' , 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
|
完整示例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
#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/<string:filename>' , 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/<string:filename>' , 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)
|
基本示例就以上这些了!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/weixin_36380516/article/details/80347192