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 解析html之BeautifulSoup
Jul 07 Python
python获取一组汉字拼音首字母的方法
Jul 01 Python
Python迭代和迭代器详解
Nov 10 Python
python 3.5下xadmin的使用及修复源码bug
May 10 Python
Python md5与sha1加密算法用法分析
Jul 14 Python
python调用百度地图WEB服务API获取地点对应坐标值
Jan 16 Python
python basemap 画出经纬度并标定的实例
Jul 09 Python
在OpenCV里使用特征匹配和单映射变换的代码详解
Oct 23 Python
利用python实现PSO算法优化二元函数
Nov 13 Python
python使用ctypes调用扩展模块的实例方法
Jan 28 Python
利用python 读写csv文件
Sep 10 Python
Python爬虫逆向分析某云音乐加密参数的实例分析
Dec 04 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
Apache2中实现多网站域名绑定的实现方法
2011/06/01 PHP
thinkPHP导出csv文件及用表格输出excel的方法
2015/12/30 PHP
浅谈Laravel核心解读之Console内核
2018/12/02 PHP
PHP连接及操作PostgreSQL数据库的方法详解
2019/01/30 PHP
ASP.NET中使用后端代码注册脚本 生成JQUERY-EASYUI的界面错位的解决方法
2010/06/12 Javascript
JavaScript高级程序设计 阅读笔记(二十一) JavaScript中的XML
2012/09/14 Javascript
js 获取坐标 通过JS得到当前焦点(鼠标)的坐标属性
2013/01/04 Javascript
解决jquery1.9不支持browser对象的问题
2013/11/13 Javascript
关闭浏览器输入框自动补齐 兼容IE,FF,Chrome等主流浏览器
2014/02/11 Javascript
js如何判断用户是在PC端和还是移动端访问
2014/04/24 Javascript
node.js中的fs.appendFileSync方法使用说明
2014/12/17 Javascript
javascript入门之string对象【新手必看】
2016/11/22 Javascript
几种tab切换详解
2017/02/03 Javascript
js读取json文件片段中的数据实例
2017/03/09 Javascript
详解在Angular项目中添加插件ng-bootstrap
2017/07/04 Javascript
js实现单张图片平移切换效果
2017/10/11 Javascript
原生JS实现的简单轮播图功能【适合新手】
2018/08/17 Javascript
python实现绘制树枝简单示例
2014/07/24 Python
Python设计模式编程中Adapter适配器模式的使用实例
2016/03/02 Python
Python中用psycopg2模块操作PostgreSQL方法
2017/11/28 Python
Python中判断输入是否为数字的实现代码
2018/05/26 Python
使用Anaconda3建立虚拟独立的python2.7环境方法
2018/06/11 Python
python爬虫之urllib,伪装,超时设置,异常处理的方法
2018/12/19 Python
Python中字符串String的基本内置函数与过滤字符模块函数的基本用法
2019/05/27 Python
Python爬虫实现“盗取”微信好友信息的方法分析
2019/09/16 Python
python数据化运营的重要意义
2019/11/25 Python
Python字符串三种格式化输出
2020/09/17 Python
中国宠物用品商城:E宠商城
2016/08/27 全球购物
Linux操作面试题
2015/02/11 面试题
新浪微博实习心得体会
2014/01/27 职场文书
感恩节红领巾广播稿
2014/02/11 职场文书
公务员学习习总书记“三严三实”思想汇报
2014/09/19 职场文书
2014法制宣传日活动总结范文
2014/11/01 职场文书
财务负责人岗位职责
2015/02/03 职场文书
2016年暑期教师培训心得体会
2016/01/09 职场文书
opencv用VS2013调试时用Image Watch插件查看图片
2021/07/26 Python