前端上传图片给后端django处理,处理的图片返回给前端
后台-插件-广告管理-内容页头部广告(手机) |
概述一下处理逻辑:
点击某个按钮,执行某个函数,该函数打开文件选择器->
将选择的文件转成base64字符串,并通过axios传给后端->
后端接收base64字符串,并将其转换成opencv格式的图片->
opencv格式的图片经过处理得到一个新的opencv格式图片,该图片转成base64字符串->
该base64字符串返回给前端,前端进行渲染
实操:
1. 前端安装必要的库
前端库:axios@1.6.7 qs@6.11.0
2. 页面元素
"store.img1"%20style="width:100%"%20alt=""> <img%20:src="store.img2"%20style="width:100%"%20alt="">%20这是两个img标签,src中的img1表示处理前的图片(base64字符串),img2表示处理后的图片(base64字符串)
%203.%20浏览器选择图片并转化为base64字符串
%20这里以点击一个按钮为例(这个按钮用一个img标签代替,当然你也可以直接用一个div代替,给这个img或者div一个click事件即可)
%20 <img%20@click="store.upload"%20src="./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标签就也可以显示图片了
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。
在线投稿:投稿 站长QQ:1888636
后台-插件-广告管理-内容页尾部广告(手机) |