Flask保存图片与展示

Posted 张子恒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask保存图片与展示相关的知识,希望对你有一定的参考价值。

配置项

为了方便的图片的保存与展示,可以在 配置文件中,指明 图片资源的路径

 1 import os
 2  3  4 class Config(object):
 5     DEBUG = True
 6     SQLALCHEMY_DATABASE_URI = \'mysql://root:mysql@127.0.0.1:3306/day08\'
 7     SQLALCHEMY_TRACK_MODIFICATIONS = False
 8  9     # 构建项目所在的 绝对路径,也就是 day08 的绝对路径
10     BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
11     # 自己指明的 图片上传路径
12     MEDIA_ROOT = os.path.join(BASE_DIR, \'MEDIA/\')

模型类

 1 from app.extensions import db
 2 from datetime import datetime
 3  4  5 # 分类: id、name
 6 class Cate(db.Model):
 7     __tablename__ = \'tb_cate\'
 8     id = db.Column(db.Integer, primary_key=True, autoincrement=True)
 9     name = db.Column(db.String(32), unique=True, nullable=False)
10 11 12 # 新闻: id、title、content、count、img、time、cate_id
13 class News(db.Model):
14     __tablename__ = \'tb_news\'
15     id = db.Column(db.Integer, primary_key=True, autoincrement=True)
16     title = db.Column(db.String(32), unique=True, nullable=False)
17     content = db.Column(db.Text)
18     count = db.Column(db.Integer, default=0)
19     img = db.Column(db.String(256))  # 图片字段中,存放的是  图片地址,并不是图片本身
20     time = db.Column(db.DateTime, default=datetime.now)
21     cate_id = db.Column(db.Integer, db.ForeignKey(\'tb_cate.id\'))
22     # 关系
23     cate = db.relationship(\'Cate\', backref=\'news\')

 


工具集

自定义函数,将图片保存到本地

 1 import os
 2 from uuid import uuid4
 3 from flask import current_app  # current_app 属于应用上下文,代表项目中的app本身
 4  5  6 def img_upload(img):
 7     if not img:
 8         return None
 9 10     # 将图片名按照 .  进行切分, 找到最后一个元素,也就是  文件的后缀名
11     end_name = img.filename.rsplit(\'.\')[-1]
12 13     # 通过文件的后缀名判断 身份为 合法的  图片
14     if end_name not in [\'jpg\', \'png\', \'gif\', \'jpeg\']:
15         return None
16 17     # 将 图片对象 存入 本地,然后将 路径 存入 数据库
18     MEDIA = current_app.config[\'MEDIA_ROOT\']  # 从app的配置项,取出 MEDIA的路径
19     filename = str(uuid4()) + \'.\' + end_name  # 为了生成一个不重复的 文件名
20     img_path = os.path.join(MEDIA, filename)  # 将路径和文件名拼接在一起,方便保存文件
21 22     img.save(img_path)  # 将图片对象保存到 本地
23 24     return filename

视图

图片上传

上传图片的逻辑, 和一般的 添加数据流程一样,只是多了一步: 将图片对象保存到本地

 1 class NewsView(Resource):
 2     def post(self):
 3         # 1. 创建解析参数的对象
 4         parser = reqparse.RequestParser()
 5         # 2. 指明需要解析的参数
 6         parser.add_argument(\'title\', type=str, location=\'form\', required=True)
 7         parser.add_argument(\'content\', type=str, location=\'form\')
 8         parser.add_argument(\'count\', type=int, location=\'form\', default=0)
 9         parser.add_argument(\'cate_id\', type=int, location=\'form\', required=True)
10         parser.add_argument(\'img\', type=FileStorage, location=\'files\')
11 12         # 3. 获取具体的参数
13         args = parser.parse_args()
14 15         title = args.get(\'title\')
16         content = args.get(\'content\')
17         count = args.get(\'count\')
18         cate_id = args.get(\'cate_id\')
19         img = args.get(\'img\')
20 21         # 利用自定义函数,将图片保存到本地
22         filename = img_upload(img)
23 24         # 4. 创建对象, 注意:图片存储的只是 从media之后的  图片路径
25         news = News(title=title, content=content, count=count, img=filename, cate_id=cate_id)
26         # 5. 添加到 事务中
27         db.session.add(news)
28         # 6. 提交事务
29         try:
30             db.session.commit()
31         except:
32             return {
33                        \'msg\': \'添加失败\'
34                    }, 500
35         # 7. 返回响应
36         return {
37                    \'id\': news.id,
38                    \'title\': news.title,
39                    \'img\': news.img
40                }, 201

图片展示

图片展示,实际就是 将 图片内容读取为文件流,做为响应返回

http://127.0.0.1:5000/media/filename

 1 class ImgView(Resource):
 2     def get(self, filename):
 3         # 1. 从配置项中读取 media目录的 路径
 4         MEDIA = current_app.config[\'MEDIA_ROOT\']
 5         # 2. 拼接除图片的完成路径
 6         img_path = os.path.join(MEDIA, filename)
 7  8         # 3. 按照二进制方式打开文件,读到的内容为 二进制文件流,方便接下来的网络传输
 9         try:
10             with open(img_path, \'rb\') as f:
11                 img = f.read()
12         except FileNotFoundError:
13             return None, 404
14 15         # 4. 自定义响应
16         resp = make_response(img)
17         # 5. 声明响应体的类型 为  图片
18         resp.headers[\'Content-Type\'] = \'image/png\'
19         # 6. 返回响应
20         return resp

 

1 # 路由匹配,获取文件名
2 
3 api.add_resource(ImgView, \'/media/<string:filename>\')

以上是关于Flask保存图片与展示的主要内容,如果未能解决你的问题,请参考以下文章

Flask - 使用相同名称覆盖图像并显示新图像

Flask+Bootstrap展示MM图片在网页上,从而更好地挑选富婆??

python Flask中返回图片流给前端展示

如何在不使用意图的片段中拍摄和保存图片?

Tensorflow机器学习入门——cifar10数据集的读取展示与保存

图片展示js特效