网络编程
位置:首页>> 网络编程>> Python编程>> django和vue互传图片并进行处理和展示

django和vue互传图片并进行处理和展示

作者:吕大娟  发布时间:2021-04-24 20:39:16 

标签:vue与,django,互传

----------记录一下这两天做的一个小demo

功能是要实现一个从前端传给后端一张图片,在后端完成目标检测后,传给前端,前端接收后并展示。

一、前端上传图片到后端

1、这一部分要用到elelent uiupload组件,代码如下:

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')

因为前端传的时候并没有给名字,直接就传过来了,所以就按&ldquo;file&rdquo;名处理。

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=&ldquo;handlesuccess&rdquo;)

然后需要注意的是展示图片时,需要在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
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com