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实现提取百度搜索结果的方法
May 19 Python
Python实现的破解字符串找茬游戏算法示例
Sep 25 Python
Python实现的多叉树寻找最短路径算法示例
Jul 30 Python
浅谈python str.format与制表符\t关于中文对齐的细节问题
Jan 14 Python
python tkinter基本属性详解
Sep 16 Python
使用python将最新的测试报告以附件的形式发到指定邮箱
Sep 20 Python
解决python 读取excel时 日期变成数字并加.0的问题
Oct 08 Python
python深copy和浅copy区别对比解析
Dec 26 Python
浅谈tensorflow模型保存为pb的各种姿势
May 25 Python
使用scrapy ImagesPipeline爬取图片资源的示例代码
Sep 28 Python
Python中常见的反爬机制及其破解方法总结
Jun 10 Python
4种方法python批量修改替换列表中元素
Apr 07 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解析html类库simple_html_dom(详细介绍)
2013/07/05 PHP
php/js获取客户端mac地址的实现代码
2013/07/08 PHP
php header功能的使用
2013/10/28 PHP
php获取网卡的MAC地址支持WIN/LINUX系统
2014/04/30 PHP
PHP实现数组递归转义的方法
2014/08/28 PHP
windows中为php安装mongodb与memcache
2015/01/06 PHP
在Nginx上部署ThinkPHP项目教程
2015/02/02 PHP
使用laravel和ajax实现整个页面无刷新的操作方法
2019/10/03 PHP
前淘宝前端开发工程师阿当的PPT中有JS技术理念问题
2010/01/15 Javascript
学习JavaScript的最佳方法分享
2011/10/21 Javascript
两个数组去重的JS代码
2013/12/04 Javascript
javascript实现全角与半角字符的转换
2015/01/07 Javascript
javascript实现全角半角检测的方法
2015/07/23 Javascript
JavaScipt中栈的实现方法
2016/02/17 Javascript
AngularJS 实现弹性盒子布局的方法
2016/08/30 Javascript
jQuery判断邮箱格式对错实例代码讲解
2017/04/12 jQuery
vue裁切预览组件功能的实现步骤
2018/05/04 Javascript
jQuery模拟html下拉多选框的原生实现方法示例
2019/05/30 jQuery
微信公众号网页分享功能开发的示例代码
2020/05/27 Javascript
JavaScript缓动动画函数的封装方法
2020/11/25 Javascript
[01:11:27]2018DOTA2亚洲邀请赛小组赛 A组加赛 Newbee vs Optic
2018/04/03 DOTA
[05:49]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS 选手采访
2021/03/11 DOTA
开始着手第一个Django项目
2015/07/15 Python
PyQt+socket实现远程操作服务器的方法示例
2019/08/22 Python
Python绘制三角函数图(sin\cos\tan)并标注特定范围的例子
2019/12/04 Python
iphoneX 适配客户端H5页面的方法教程
2017/12/08 HTML / CSS
Draper James官网:知名演员瑞茜·威瑟斯彭所创品牌
2017/10/25 全球购物
诗普兰迪官方网站:Splendid
2018/09/18 全球购物
SHEIN台湾:购买最新流行女装服饰
2019/05/18 全球购物
家长对孩子的评语
2014/04/18 职场文书
《棉鞋里的阳光》教学反思
2014/04/24 职场文书
品牌服务方案
2014/06/03 职场文书
爱护公物标语
2014/06/24 职场文书
优秀团员事迹材料1000字
2014/08/20 职场文书
施工安全保证书
2015/05/09 职场文书
Java Shutdown Hook场景使用及源码分析
2021/06/15 Java/Android