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动态监控日志内容的示例
Feb 16 Python
python读取浮点数和读取文本文件示例
May 06 Python
Python3中常用的处理时间和实现定时任务的方法的介绍
Apr 07 Python
基于python socketserver框架全面解析
Sep 21 Python
Python二进制串转换为通用字符串的方法
Jul 23 Python
python调用摄像头显示图像的实例
Aug 03 Python
widows下安装pycurl并利用pycurl请求https地址的方法
Oct 15 Python
numpy 对矩阵中Nan的处理:采用平均值的方法
Oct 30 Python
Python3 单行多行万能正则匹配方法
Jan 07 Python
如何利用Python分析出微信朋友男女统计图
Jan 25 Python
Python3直接爬取图片URL并保存示例
Dec 18 Python
python实现替换word中的关键文字(使用通配符)
Feb 13 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中去掉字符串首尾空格的方法
2012/05/19 PHP
用PHP写的一个冒泡排序法的函数简单实例
2016/05/26 PHP
php+resumablejs实现的分块上传 断点续传功能示例
2017/04/18 PHP
PHP中$GLOBALS与global的区别详解
2019/03/21 PHP
Jquery替换已存在于element上的event的方法
2010/03/09 Javascript
jWiard 基于JQuery的强大的向导控件介绍
2011/10/28 Javascript
js二级地域选择的实现方法
2013/06/17 Javascript
javascript中setTimeout和setInterval的unref()和ref()用法示例
2014/11/26 Javascript
javascript实现滑动解锁功能
2014/12/31 Javascript
原生js结合html5制作简易的双色子游戏
2015/03/30 Javascript
使用CamanJS在Web页面上处理图像的技巧
2015/08/18 Javascript
基于JavaScript实现简单的随机抽奖小程序
2016/01/05 Javascript
jQuery toggle 代替方法
2016/03/22 Javascript
AngularJS基础 ng-model-options 指令简单示例
2016/08/02 Javascript
JS 事件绑定、事件监听、事件委托详细介绍
2016/09/28 Javascript
js中利用cookie实现记住密码功能
2020/08/20 Javascript
原生JS实现图片翻书效果
2017/02/16 Javascript
前端主流框架vue学习笔记第一篇
2017/07/26 Javascript
webpack分离css单独打包的方法
2018/06/12 Javascript
Node.js 多线程完全指南总结
2019/03/27 Javascript
[00:43]TI7不朽珍藏III——幽鬼不朽展示
2017/07/15 DOTA
一个基于flask的web应用诞生 用户注册功能开发(5)
2017/04/11 Python
python实现Virginia无密钥解密
2019/03/20 Python
阿里云ECS服务器部署django的方法
2019/08/29 Python
Pytorch: 自定义网络层实例
2020/01/07 Python
使用Pycharm在运行过程中,查看每个变量的操作(show variables)
2020/06/08 Python
python exit出错原因整理
2020/08/31 Python
Pycharm配置autopep8实现流程解析
2020/11/28 Python
装上这 14 个插件后,PyCharm 真的是无敌的存在
2021/01/11 Python
New Balance波兰官方商城:始于1906年,百年慢跑品牌
2017/08/15 全球购物
爱尔兰电子产品购物网站:Komplett.ie
2018/04/04 全球购物
在阿尔卑斯山或希腊度过快乐假期:Alpine Elements
2019/12/28 全球购物
播音主持专业个人自我评价
2014/01/09 职场文书
《春晓》教学反思
2014/04/20 职场文书
水利水电专业自荐信
2014/07/08 职场文书
小学校园文化建设汇报材料
2014/08/19 职场文书