django和vue互传图片并进行处理和展示
作者:吕大娟 发布时间:2021-04-24 20:39:16
标签:vue与,django,互传
----------记录一下这两天做的一个小demo
功能是要实现一个从前端传给后端一张图片,在后端完成目标检测后,传给前端,前端接收后并展示。
一、前端上传图片到后端
1、这一部分要用到elelent ui
的upload
组件,代码如下:
view中
<el-upload
:action="uploadURL"
list-type="picture-card"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:on-success="handlesuccess">
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
method中
handlePictureCardPreview(file) {
// 这个“file”里默认包含了这张图片的所有信息:名字,url...
console.log("打印下zi",file);
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
data中
uploadURL:process.env.VUE_APP_BASE_API,
这里边on-preview
是点击文件列表中已上传的文件时的钩子,这个操作只是把本地图片上传到前端并展示到前端页面中了。
2、要把它传给后端的话,action这个钩子需要这么写:
uploadURL:process.env.VUE_APP_BASE_API+"/test_moudle/test/",
也就是说在后边加上路由。
二、后端接收图片并检测
1、首先接收图片
img = request.FILES.get('file')
因为前端传的时候并没有给名字,直接就传过来了,所以就按“file”
名处理。
2、然后要对图片进行检测,由于我的检测代码是写死的,它需要的是一个图片路径,如下所示,
parser.add_argument('--source', type=str, default='windmill/images/test', help='file/dir/URL/glob, 0 for webcam')
所以我没办法把前端传过来的图片直接处理并输入检测网络,最后只能把图片保存一下,然后把保存路径给检测网络:
img = request.FILES.get('file')
print('打印名称和类型',type(img),img)
base_dir = settings.BASE_DIR
upload_dir = os.path.join(base_dir, 'upload')
path = os.path.join(upload_dir, img.name)
with open(path, 'wb+') as f:
for chunk in img.chunks():
f.write(chunk)
timestrap = str(time.time())
把路径给检测网络
parser.add_argument('--source', type=str, default=path, help='file/dir/URL/glob, 0 for webcam')
三、把检测完的图片传给前端
这一步需要把图片转为base64形式的才能传给前端
......这里省略了检测代码
res_path = os.path.join(base_dir, 'runs', 'detect', timestrap, img.name)
if os.path.exists(res_path):
print('有检测结果吧')
with open(res_path, 'rb') as f:
data = f.read()
result['msg'] = bytes.decode(base64.b64encode(data))
else:
result['msg'] = '有图片上传但是没有检测结果'
else:
result['msg'] = '没有图片上传'
return JsonResponse(result)
四、前端接收base64图片并展示
<div class="myres">
<img width="20%" :src="'data:image/png;base64,'+detect_picture">
</div>
handlesuccess(response, file, fileList){
console.log("打印下",file,fileList);
this.detect_picture = response.msg;
},
在这里头接收后端的图片时并处理的钩子是upload
组件中的on-success
(on-success=“handlesuccess”)
然后需要注意的是展示图片时,需要在src(路径)前加'data:image/png;base64,'
:
<img width="20%" :src="'data:image/png;base64,'+detect_picture">
这样一个检测小demo就完成了-----------
完整代码
后端
def test(request):
result = {}
if request.method == 'POST':
#你要关注的 1、从前端接收图片
img = request.FILES.get('file')
print('打印名称和类型',type(img),img)
base_dir = settings.BASE_DIR # 当前的最高级目录(dvadmin-backend)
upload_dir = os.path.join(base_dir, 'upload') # 在主目录下新建文件夹
path = os.path.join(upload_dir, img.name) # 把前端传过来的图片保存在新建的upload文件夹中
with open(path, 'wb+') as f:
for chunk in img.chunks():
f.write(chunk)
timestrap = str(time.time())
# 从这里开始
parser = argparse.ArgumentParser()
# 1、选模型
# parser.add_argument('--weights', nargs='+', type=str, default='runs/train/exp/weights/best.pt', help='model.pt path(s)')
parser.add_argument('--weights', nargs='+', type=str,
default=r'D:\Desktop\lfj\code\实验结果\expyolov5s原2\weights\best.pt', help='model.pt path(s)')
# parser.add_argument('--source', type=str, default='windmill/images/test', help='file/dir/URL/glob, 0 for webcam')
parser.add_argument('--source', type=str, default=path, help='file/dir/URL/glob, 0 for webcam')
# parser.add_argument('--source', type=str, default=img, help='file/dir/URL/glob, 0 for webcam')
# 输入图片的大小 默认640
parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=640, help='inference size (pixels)')
# 置信度阈值 默认0.25
parser.add_argument('--conf-thres', type=float, default=0.25, help='confidence threshold')
# 做Nms的iou阈值
parser.add_argument('--iou-thres', type=float, default=0.45, help='NMS IoU threshold')
# 保留的最大检测框数量,每张图片中检测目标的个数最多为1000类
parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image')
# 设置设备CPU/GPU,这个可以不用设置
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
# 是否展示预测之后的图片
parser.add_argument('--view-img', action='store_true', help='show results')
# 是否将预测的框坐标以txt文件形式保存,默认False,使用save-txt在路径runs/detect/exp/labels/.txt下生成每张图片预测的txt文件
parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
# 是否将置信度conf也保存到txt文件中
parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes')
parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
# 设置只保留某一部分类别,形如0或者0 2 3
parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
parser.add_argument('--augment', action='store_true', help='augmented inference')
parser.add_argument('--visualize', action='store_true', help='visualize features')
parser.add_argument('--update', action='store_true', help='update all models')
# 保存测试日志的文件夹路径
parser.add_argument('--project', default='runs/detect', help='save results to project/name')
# 用时间戳生成文件夹timestrap 保存测试日志文件夹的名字,所以最终保存在project/name中
parser.add_argument('--name', default=timestrap, help='save results to project/name')
#
parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
# 画框的线条粗细---
parser.add_argument('--line-thickness', default=3, type=int, help='bounding box thickness (pixels)')
parser.add_argument('--hide-label s', default=False, action='store_true', help='hide labels')
parser.add_argument('--hide-conf', default=False, action='store_true', help='hide confidences')
parser.add_argument('--half', action='store_true', help='use FP16 half-precision inference')
opt = parser.parse_args(args=[])
main(opt)
# 到这里结束,这些你都不用管
# 2、图片传给前端
# 找到刚刚检测的图片,并把它转为base64形式,传给前端
res_path = os.path.join(base_dir, 'runs', 'detect', timestrap, img.name)
if os.path.exists(res_path):
print('有检测结果吧')
with open(res_path, 'rb') as f:
data = f.read()
result['msg'] = bytes.decode(base64.b64encode(data))
else:
result['msg'] = '有图片上传但是没有检测结果'
else:
result['msg'] = '没有图片上传'
return JsonResponse(result)
前端
<template>
<div class="container">
<!-- <div class="mysel" style="margin-bottom: 20px;">
<el-select v-model="value" placeholder="请选择检测模型" >
</el-select>
</div> -->
<el-upload
:action="uploadURL"
list-type="picture-card"
multiple
:limit="6"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:on-success="handlesuccess">
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
<el-button icon="" type="text" @click="but_test">
点击识别
</el-button>
<div class="myres">
<img width="20%" :src="'data:image/png;base64,'+detect_picture">
</div>
</div>
</template>
<script>
import request from "@/utils/request";
import axios from "axios";
export default {
components: {
},
data() {
return {
// 图片要传到服务端的哪里(路由=process.env.VUE_APP_BASE_API+你要传图片的接口)
uploadURL:process.env.VUE_APP_BASE_API+"/test_moudle/updateinfo/",
// 前端上传的图片的地址
dialogImageUrl: '',
dialogVisible: false,
// 后端传过来的图片的base64形式
detect_picture: '',
queryParams: {
ipaddr: undefined,
userName: undefined
},
};
},
computed: {
},
watch: {
},
activeId: {
},
mounted() {
},
created(){
// this.visualize_data()
},
methods: {
// 测试前后端是否连通的函数
visualize_data() {
return request({
url: "/test_moudle/test", //get请求最后没有'/'
method: "get",
}).then(response=>{
console.log('怎么可以这样',response)
});
},
// 处理图片预览效果
handlePreview(){},
// 处理移除图片的操作
handleRemove(file, fileList) {
console.log(file, fileList);
},
// 点击文件列表中已上传的文件时的钩子
handlePictureCardPreview(file) {
// 这个“file”里默认包含了这张图片的所有信息:名字,url...
console.log("打印下zi",file);
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
but_test(){
console.log("这个函数是否执行")
this.uploadURL = process.env.VUE_APP_BASE_API+"/test_moudle/test/";
},
// 用这个函数去接收后端传过来的图片
handlesuccess(response, file, fileList){
console.log("打印下",file,fileList);
this.detect_picture = response.msg;
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 搜索按钮操作 */
handleQuery() {
this.pageNum = 1;
// this.getList();
},
}
};
</script>
写了3个demo,前端没变哈哈哈哈,变得只是后端怎么处理图片,怎么传给前端
来源:https://blog.csdn.net/weixin_42855400/article/details/125938437
0
投稿
猜你喜欢
- defaultdict是普通字典dict的一个子类。通过collections库的defaultdict()方法创建。defaultdict
- 1、找到mysql安装路径D:\xxx\MYSQL\MySQL Workbench CE 6.0.8下的mysqldump.exe,由于脚本
- 1、从外部文档中粘贴时,如果不想要其格式,只要文字,可以使用“Edit->paste as text”命令,而不要直接Ctrl+V。2
- 1. 相对与比较老的环境,建议使用第二个 set dbconnection=Server.CREATEOBJECT("ADODB.
- 表查询: 合并查询:使用union关键字,可将满足条件的重复行去掉。 select ename,sal,job from emp where
- 上次我重新修改了UBB的转换后,又很多朋友反映日文显示的时候出错了。我在本地测试了一下,结果出现了 Invalid procedure ca
- 安装selenium打开命令控制符输入:pip install -U selenium火狐浏览器安装firebug:www.firebug.
- 概述数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能导致脏读、脏写、不可重复度和幻读。这些问题的本
- 本文以实例详解了python的迭代器与生成器,具体如下所示:1. 迭代器概述: 迭代器是访问集合元素的一种方式。迭代器对象从集合的
- 引言第一次了解python的WSGI,可能描述的不太准确。本篇文章所依赖的python环境为:什么是WSGIWSGI也称之为web服务器通用
- 本文实例为大家分享了python使用Matplotlib画条形图的具体代码,供大家参考,具体内容如下数据中国的四个直辖市分别为北京市、上海市
- MySQL如何查看元数据锁阻塞在哪里操作步骤:1、session 1 执行: start transaction;  
- 读取文件时报错:xlrd.biffh.XLRDError: Unsupported format, or corrupt file: Exp
- ①差集方法一:if __name__ == '__main__':a_list = [{'a' : 1},
- sqllite里面并没有与numpy的array类型对应的数据类型,通常我们都需要将数组转换为text之后再插入到数据库中,或者以blob类
- 1、生成 servie.yaml1.1、yaml转jsonservice模板yamlapiVersion: v1kind: Servicem
- 应用正则表达式的全局匹配,可以匹配出字符出现的次数,比较这些次数,将最大的保存并返回。代码如下: var countMost = funct
- 现在已经是Python 3.8的最后一个alpha版本,接着就是本月底要发布的的3.8.0 beta 1了。按规定,3.8已经不会再添加(修
- python中字典是非常常用的数据类型,了解各种方法的作用及优缺点对于字典的使用非常有用。dict.clear() 的方法用于清空所有的键值
- TEMPLATESDjango 1.8的新特性一个列表,包含所有在Django中使用的模板引擎的设置。列表中的每一项都是一个字典,包含某个引