前端上传图片给后端django处理,处理的图片返回给前端

概述一下处理逻辑:

点击某个按钮,执行某个函数,该函数打开文件选择器->

将选择的文件转成base64字符串,并通过axios传给后端->

后端接收base64字符串,并将其转换成opencv格式的图片->

opencv格式的图片经过处理得到一个新的opencv格式图片,该图片转成base64字符串->

该base64字符串返回给前端,前端进行渲染

实操:

1. 前端安装必要的库

前端库:axios@1.6.7     qs@6.11.0

2. 页面元素

<img :src="store.img1" style="width:100%" alt="">
<img :src="store.img2" style="width:100%" alt="">

这是两个img标签,src中的img1表示处理前的图片(base64字符串),img2表示处理后的图片(base64字符串)

3. 浏览器选择图片并转化为base64字符串

这里以点击一个按钮为例(这个按钮用一个img标签代替,当然你也可以直接用一个div代替,给这个img或者div一个click事件即可)

<img @click="store.upload" src="./assets/up.png" alt="" height="49px">

点击img,触发upload函数,upload函数:

upload(){
  var input = document.createElement('input');input.type = 'file';
  input.addEventListener('change',e => {
      var file = e.target.files[0];//console.log(file.name,file.type,);
        let reader=new FileReader();
        reader.readAsDataURL(file)
        reader.onload=e=>{
          let base64string=e.target.result
          this.img1=base64string
          console.log(base64string);
          axios.post('http://127.0.0.1:8000/test1/upload',qs.stringify({name:base64string}))
            .then(response=>{console.log(response.data);this.img2=response.data.msg;})
      }
  })
  input.click();
},

解释一下这个函数的大概逻辑,先创建一个input标签类型为file(那么为什么不直接再页面中创建一个input标签嘞,问就是自带的input标签太丑了。。。,反正只是为了弹出一个文件选择框方便选择文件而已,就用这种方式好了)

接着为这个input标签添加change事件,该事件的回调函数中将选择的文件的第一个存储到变量file中,接着file通过reader.readAsDataURL(file)将file变量转成base64格式的字符串(也就是文件转字符串),转换完成后还有个回调函数onload,里面将这个base64字符串用base64string这个变量进行赋值,并且将base64字符串直接赋值给img1,好让之前的第一个img标签显示原始图片。然后通过axios将base64string传入后端。

这里需要注意一件事,传入给后端的base64数据:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASkAAAEpAQAAAADn4ukvAAACCklEQVR4nO3aQW6jQBSE4b+ACO9gN0t8EzInyVEMNzM3sW8Ai5GMZKhZgOxJVpGcCZg0K9R8clcj6wleI/OJo44+oyCwwAILLLBPs07TsadPLOmVbjfMY7uFs22BpbbtI90O4FDvswuybbeLZ9sCGyRVAENsKJscQNJ+Bdk2xFKPAMV5942TbpglHwccmebtdBn+46Q/h823NzbQQC+grlD6Bwx0C2bbDOslSa+QXmX5WLRgSVK+eLanZvj9cQWg+DBarXkJT8CGCGpJSkdccZaS8O/9KtbtsGSfMvcRQGH3Ea5ujxCrX8JKWQKQXQaNquui7W8PZPEYaeFsW2GdEst2kxOPyMfpmqvylF0WzrYBNt/DZt9l/fTWJmn6gS4Uh8fZ9LJWTh0GS2ULwOG4gmzPzzopNrX2WZeOTM2H2IZmv3i2DbDMHiS7ydOrxcFNzhChqjwtnu25WQLQ5fHV0Lxm/U6G5q3N8T8PDqtewupZNr2slT7v4kFQnkgdisNXsftuBYAqzjlDBITi8CDDttt5t6JoU4/MJzaUpyz0HB5hc0NySODwm+wyvFhAzlR5i3bBbNtkrihaYptDvf+uSX8E65RY95JbH5qwU/wQe197fdsgnmtv6Pc+xqba28+VlvSaaPrqbHgZAbpfl8WybYBNDcn7d3zxdJpdGDG3bs+alxBYYIEF9nTsL3d0Co4PuPsxAAAAAElFTkSuQmCC

这里是一大段的,需要注意前面有data:image/png;base64,开头,这一大段可以直接赋值给img1,让img标签显示图片。并且需要注意的是“data:image/png;base64,”表示之前选择的图片格式是png,不能是其他格式,那么如果之前选择的是jpg格式的图片,这里应该显示为“data:image/jpg;base64,”

4. django接收base64格式图片

def upload(request):
    base64string=request.POST.get("name")
    print(base64string)
    img = base64.b64decode(base64string.split(',')[1])
    img_np = numpy.fromstring(img, dtype='uint8')
    new_img_np = cv2.imdecode(img_np, 1)
    barcodes=pyzbar.decode(new_img_np)
    print("检测到二维码个数:"+str(len(barcodes)))
    if len(barcodes):
        barcode = barcodes[0]
        (x, y, w, h) = barcode.rect
        cv2.rectangle(new_img_np, (x, y), (x + w, y + h), (0, 0, 225), 2)
        img_str = cv2.imencode('.png', new_img_np)[1].tostring()
        b64_code = base64.b64encode(img_str)
        print(b64_code)
        return JsonResponse({'state':0,"msg":"data:image/png;base64,"+str(b64_code).split("'")[1]})
        # cv2.imwrite("./test1/res_imgs/ddd2.png",new_img_np)
    return JsonResponse({'state':0,"msg":base64string}) 

解释一个这个函数,首先获取前端传给我们的base64字符串,并将数据赋值给变量base64string,由于此时这个变量里头是有data:image/png;base64前缀的,转格式之前需要通过base64string.split(',')[1]来去掉前缀,去掉之后再进行转格式,最终将转格式得到的opencv格式的图片用new_img_np来接收。然后就可以对这个new_img_np进行处理了。

由于作者这里是需要实现一个二维码检测,之后将检测图片里面的二维码进行框选,因此执行cv2.rectangle(new_img_np, (x, y), (x + w, y + h), (0, 0, 225), 2)将框框放在new_img_np上面(读者可以进行别的处理),之后对new_img_np进行转格式,得到b64_code这个base64格式的字符串,但是这个字符串如果直接打印是这个样子:

......

前面有b’,后面有个尾巴‘,这两个东东都是不需要的,因此去除,并且加上前缀data:image/png;base64,给返回给前端

5.前端接收base64字符串

这里实际上就涉及第三点的函数了,其中axios发送消息之后还有个回调函数:

直接给img2赋值后端传回来的base64字符串,然后第二个img标签就也可以显示图片了

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值