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

----------记录一下这两天做的一个小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')

因为前端传的时候并没有给名字,直接就传过来了,所以就按“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,前端没变哈哈哈哈,变得只是后端怎么处理图片,怎么传给前端

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 你可以回答这个问题。django-vue-admin 是一个基于 Django 和 Vue.js 的全栈开发框架,可以快速搭建后台管理系统。它提供了丰富的组件和插件,可以帮助开发者快速构建出美观、易用的管理界面。 ### 回答2: django-vue-admin是一个基于Django和Vue.js开发的开源管理系统框架,旨在帮助开发者快速构建和定制现代化的管理系统。它采用前后端分离的架构,后端使用Django提供API接口,前端使用Vue.js进行展示和交。 使用django-vue-admin,开发者可以快速搭建一个具备基本功能的管理系统。框架提供了一套完整的通用模型和视图,开发者只需根据自己的需求进行配置和扩展即可实现快速开发。同时,它采用了模块化和组件化的设计,开发者可以方便地替换和定制界面的各个组件,实现个性化的界面展示django-vue-admin还提供了丰富的功能模块,如用户管理、权限管理、角色管理、菜单管理等,开发者可以根据项目需要进行选择和集成。框架还支持多语言和多主题的配置,方便开发者根据不同用户需求进行界面定制。 此外,django-vue-admin还面向中小型项目进行了性能优化,采用了异步加载、缓存和CDN加速等技术,提高了系统的响应速度和用户体验。 总的来说,django-vue-admin是一个强大而灵活的管理系统开发框架,它简化了开发者的开发流程,提高了开发效率。无论是快速搭建简单的管理系统,还是进行个性化的定制开发,都可以选择django-vue-admin作为开发工具。 ### 回答3: django-vue-admin 是一个用于快速开发后台管理系统的开源项目。它的主要特点是结合了 Django 和 Vue.js 框架的优势,使开发者能够高效地创建功能完善、界面友好的管理系统。 django-vue-admin 提供了一套基础的后台管理功能,包括用户管理、角色管理、权限管理、日志管理等。开发者可以根据自己的需求进行功能定制和扩展。 django-vue-admin 的前端使用了 Vue.js 框架,通过组件化的方式构建用户界面,并且使用了 Element-UI 组件库来提供丰富的UI组件。这使得开发者能够快速搭建出现代化、响应式的管理系统界面。后端则使用了 Django 框架,提供了强大的数据处理和权限控制能力。 在开发上,django-vue-admin 使用了前后端分离的架构,前端和后端通过 API 进行通信。这使得开发者可以独立地进行前后端开发,提高了开发效率和团队协作能力。同时,由于前后端分离的优势,django-vue-admin 的性能也得到了明显的提升。 总之,django-vue-admin 是一个功能强大、易用、高效的后台管理系统开发框架。它能够帮助开发者快速开发出现代化的后台管理系统,并且具备良好的扩展能力。无论是个人开发者还是企业开发团队,都可以利用 django-vue-admin 来构建稳定、高效的管理系统。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值