Django 实现将图片转为Base64,然后使用json传输


Posted in Python onMarch 27, 2020

最近使用Django来进行图像的传输,由于要求需要使用Json格式进行请求,所以我们尝试了二进制编码放在json里,发现bytes格式不能打入json,于是转为了base64

将图片转为json

图片转为json有2中方法,一个是二进制后再转,一个是转为矩阵以后再转。

import base64
import cv2

#通过opencv转base64
img_im= cv2.imread("D://32.png")
aa=base64.b64encode(cv2.imencode('.jpg',img_im)[1]).decode()
print(len(aa)) #17292

#通过bytes再转base64
bb=base64.b64encode(open("D://32.png", 'rb').read())
print(len(bb)) #43848

最后采用了Opencv的方式,主要发现opencv的base64编码比第二种短一半,所以用了第一种。

客户端请求发送数据格式

客户端请求服务器的base64,目前我这里发现2中,通过Postman测试。

第一种 ‘form/data':

#客户端:
image1= cv2.imread("D://32.png")
aa=base64.b64encode(cv2.imencode('.jpg',image1)[1]).decode()
r = requests.post(url, data={"image": image1})
print(r.content.decode("utf-8"))

#服务端:
def image_base64(request):
 result = request.POST.get("image")
 img_byte = base64.b64decode(result)
 img_np_arr = np.fromstring(img_byte, np.uint8)
 image = cv2.imdecode(img_np_arr, cv2.IMREAD_COLOR)
 #image 已经转为矩阵了

第二种 ‘application/json':

#客户端:
image1= cv2.imread("D://32.png")
aa=base64.b64encode(cv2.imencode('.jpg',image1)[1]).decode()
r = requests.post(url, json={"image": image1})
print(r.content.decode("utf-8"))

#服务端:
def local_ocr_base64(request):
  # result = request.POST.get("image")
  data = request.body  
  data_json=simplejson.loads(data) #data是str格式的,需要转为json
  result=data_json["image"]
  img_byte = base64.b64decode(result)
  img_np_arr = np.fromstring(img_byte, np.uint8)
  image = cv2.imdecode(img_np_arr, cv2.IMREAD_COLOR)

补充知识:Django将多个图片保存成一个URL串返回给前端

说明

Django有ImageField字段,是封装好的,使用很方便,但是一个ImageField字段只能保存一张图片的URL,我现在是想将多张图片保存在一个字段里,然后URL和URL之间用一个自定义的分隔符连接起来,这样不用为了图片再设计一个字表。

自定义上传图片

设置settings.py文件,添加如下语句

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
IMAGE_ROOT = os.path.join(MEDIA_ROOT, 'images/')
WEB_HOST_MEDIA_URL = os.path.join('http://127.0.0.1:8000', MEDIA_URL[1:], 'images/')

MEDIA_ROOT代表的是用户上传后的文件一般保存的地方,一般在放在项目目录下,例如BASE_DIR就是取得项目绝对地址。而MEDIA_URL是指URL访问时的URL。例如,

BASE_DIR: /Users/incisor/VSCodeProjects/python/Notes

那么

MEDIA_ROOT:/Users/incisor/VSCodeProjects/python/Notes/media

假设media目录下有一张图片2019.jpg,那么

MEDIA_URL: http://127.0.0.1:8000/media/

然后再通过http://127.0.0.1:8000/media/2019.jpg这个URL是可以直接访问这个图片的。

IMAGE_ROOT是我自定义的一个字段,因为我想以后可能会上传视频,或者其他一些文件,想区分开,所以我在media目录下再建了一个目录images,那么

IMAGE_ROOT: /Users/incisor/VSCodeProjects/python/Notes/media/images

WEB_HOST_MEDIA_URL是拼接URL时使用,因为我接下来要自己拼接多个图的URL,MEDIA_URL[1:]的原因时如果不去掉第一个/,那WEB_HOST_MEDIA_URL会是/media/images/,这显然不是我们想要的,所以需要把第一个/去掉。

views.py文件

前端传过来不定数量的图片,可能0张,最多9张,每个图片都做base64编码再传过来,POST请求里有个参数imgs,是一个数组,保存base64编码。

base64编码如下图所示,这只是一部分:

前面的data:image/png;base64, 除了后缀会不同,其他的是固定的,所以我会先从这里取得后缀png,再做编码转换。

import base64
import os
import re
from datetime import date, datetime
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response

from Notes.settings import IMAGE_ROOT, WEB_HOST_MEDIA_URL

@api_view(['POST',])
def images(request):
  urls = ''
  dir_name = date.today().__str__().replace('-', '_', 2) # 2019_06_21
  dirs = os.path.join(IMAGE_ROOT, dir_name) # 将日期作为目录名
  if not os.path.isdir(dirs):
    os.makedirs(dirs) # 判断目录是否存在,不存在则创建
  for img in request.data['imgs']:
    strs = img.split(',')
    suffix = re.findall(r'/(\w+?);', strs[0])[0] # 取得文件后缀
    # 拼接服务器上的文件名
    # datetime.now()取得当前时间,精确到了微秒,一般来说是唯一的了,因为目录是日期,所以文件名就去掉日期,最后会是一串数字
    img_name = re.sub(r':|\.', '', datetime.now().__str__().split(' ')[1]) + '.' + suffix 
    img_path = os.path.join(dirs, img_name)
    with open(img_path, 'wb') as out:
      out.write(base64.b64decode(strs[1])) # base64解码,再写入文件
      out.flush()
      urls += os.path.join(WEB_HOST_MEDIA_URL, dir_name, img_name) + '[/--sp--/]' # 拼接URL,URL与URL之间用[/--sp--/]隔开
  result = {}
  result['status'] = status.HTTP_200_OK
  result['message'] = '图片上传成功'
  result['urls'] = urls[:len(urls) - len('[/--sp--/]')] # 去掉末尾的[/--sp--/]
  return Response(data=result)

3、urls.py文件

from django.contrib import admin
from django.urls import path
from django.conf.urls.static import static # 需要添加这句,包含静态资源之类的
from note import views
from . import settings


urlpatterns = [
  path('notes/images/', views.images),
  path('admin/', admin.site.urls),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # 这句不设置的话,不能通过URL直接访问到图片

4、启动服务,python3 manage.py runserver

5、POST请求,然后返回对应的JSON数据

{
  "status": 200,
  "message": "图片上传成功",
  "urls": "http://127.0.0.1:8000/media/images/2019_06_21/073249204253.png[/--sp--/]http://127.0.0.1:8000/media/images/2019_06_21/073249854323.png"
}

这样在数据库方面,就可以直接用一个varchar类型来存储多张图了,前端收到URL串,再按照定好的分隔符[/?sp?/]切开后,就可以显示了。

以上这篇Django 实现将图片转为Base64,然后使用json传输就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中getattr函数和hasattr函数作用详解
Jun 14 Python
python 接口_从协议到抽象基类详解
Aug 24 Python
python与sqlite3实现解密chrome cookie实例代码
Jan 20 Python
python实现K最近邻算法
Jan 29 Python
Python Flask框架模板操作实例分析
May 03 Python
Python常见数据类型转换操作示例
May 08 Python
python列表,字典,元组简单用法示例
Jul 11 Python
pytorch下使用LSTM神经网络写诗实例
Jan 14 Python
python读取xml文件方法解析
Aug 04 Python
Python 实现3种回归模型(Linear Regression,Lasso,Ridge)的示例
Oct 15 Python
Selenium关闭INFO:CONSOLE提示的解决
Dec 07 Python
python实现银行账户系统
Feb 22 Python
python实现简单坦克大战
Mar 27 #Python
Django实现从数据库中获取到的数据转换为dict
Mar 27 #Python
Python生成器实现简单"生产者消费者"模型代码实例
Mar 27 #Python
python数据库编程 Mysql实现通讯录
Mar 27 #Python
python数据库编程 ODBC方式实现通讯录
Mar 27 #Python
django 读取图片到页面实例
Mar 27 #Python
django ListView的使用 ListView中获取url中的参数值方式
Mar 27 #Python
You might like
PHP循环函数使用介绍之PHP基础入门教程
2013/09/21 PHP
PHP实现的通过参数生成MYSQL语句类完整实例
2016/04/11 PHP
PHP二维数组实现去除重复项的方法【保留各个键值】
2017/12/21 PHP
PHP信号处理机制的操作代码讲解
2019/04/19 PHP
CLASS_CONFUSION JS混淆 全源码
2007/12/12 Javascript
JQuery live函数
2010/12/24 Javascript
纯JAVASCRIPT图表动画插件Highcharts Examples
2011/04/16 Javascript
jquery validate 自定义验证方法介绍 日期验证
2014/02/27 Javascript
jQuery实现当前页面标签高亮显示的方法
2015/03/10 Javascript
js实现最短的XML格式化工具实例
2015/03/12 Javascript
JS组件Bootstrap Table使用方法详解
2016/02/02 Javascript
原生js实现百叶窗效果及原理介绍
2016/04/12 Javascript
jQuery 翻页组件yunm.pager.js实现div局部刷新的思路
2016/08/11 Javascript
JS实现隐藏同级元素后只显示JS文件内容的方法
2016/09/04 Javascript
Nodejs中Express 常用中间件 body-parser 实现解析
2017/05/22 NodeJs
使用webpack-dev-server处理跨域请求的方法
2018/04/18 Javascript
详解Vue的钩子函数(路由导航守卫、keep-alive、生命周期钩子)
2018/07/24 Javascript
详解vue使用$http服务端收不到参数
2019/04/19 Javascript
layui在form表单页面通过Validform加入简单验证的方法
2019/09/06 Javascript
vue自动添加浏览器兼容前后缀操作
2020/08/13 Javascript
Vue2.0 ES6语法降级ES5的操作
2020/10/30 Javascript
Python中的闭包实例详解
2014/08/29 Python
python简单的函数定义和用法实例
2015/05/07 Python
Python数组定义方法
2016/04/13 Python
Python时间获取及转换知识汇总
2017/01/11 Python
浅谈numpy数组中冒号和负号的含义
2018/04/18 Python
在python中利用最小二乘拟合二次抛物线函数的方法
2018/12/29 Python
详解python中groupby函数通俗易懂
2020/05/14 Python
香港迪士尼乐园酒店预订:Hong Kong Disneyland Hotels
2017/05/02 全球购物
大学毕业生通用自我评价
2014/01/05 职场文书
2014年妇幼卫生工作总结
2014/12/09 职场文书
会计简历自我评价
2015/03/10 职场文书
python爬取某网站原图作为壁纸
2021/06/02 Python
教你用python实现12306余票查询
2021/06/30 Python
MySQL去除重叠时间求时间差和的实现
2021/08/23 MySQL
Python学习开发之图形用户界面详解
2021/08/23 Python