Django 實(shí)現(xiàn)將圖片轉(zhuǎn)為Base64,然后使用json傳輸
最近使用Django來進(jìn)行圖像的傳輸,由于要求需要使用Json格式進(jìn)行請求,所以我們嘗試了二進(jìn)制編碼放在json里,發(fā)現(xiàn)bytes格式不能打入json,于是轉(zhuǎn)為了base64
將圖片轉(zhuǎn)為json
圖片轉(zhuǎn)為json有2中方法,一個(gè)是二進(jìn)制后再轉(zhuǎn),一個(gè)是轉(zhuǎn)為矩陣以后再轉(zhuǎn)。
import base64
import cv2
#通過opencv轉(zhuǎn)base64
img_im= cv2.imread("D://32.png")
aa=base64.b64encode(cv2.imencode('.jpg',img_im)[1]).decode()
print(len(aa)) #17292
#通過bytes再轉(zhuǎn)base64
bb=base64.b64encode(open("D://32.png", 'rb').read())
print(len(bb)) #43848
最后采用了Opencv的方式,主要發(fā)現(xiàn)opencv的base64編碼比第二種短一半,所以用了第一種。
客戶端請求發(fā)送數(shù)據(jù)格式
客戶端請求服務(wù)器的base64,目前我這里發(fā)現(xiàn)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"))
#服務(wù)端:
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 已經(jīng)轉(zhuǎn)為矩陣了
第二種 ‘a(chǎn)pplication/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"))
#服務(wù)端:
def local_ocr_base64(request):
# result = request.POST.get("image")
data = request.body
data_json=simplejson.loads(data) #data是str格式的,需要轉(zhuǎn)為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)
補(bǔ)充知識:Django將多個(gè)圖片保存成一個(gè)URL串返回給前端
說明
Django有ImageField字段,是封裝好的,使用很方便,但是一個(gè)ImageField字段只能保存一張圖片的URL,我現(xiàn)在是想將多張圖片保存在一個(gè)字段里,然后URL和URL之間用一個(gè)自定義的分隔符連接起來,這樣不用為了圖片再設(shè)計(jì)一個(gè)字表。
自定義上傳圖片
設(shè)置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代表的是用戶上傳后的文件一般保存的地方,一般在放在項(xiàng)目目錄下,例如BASE_DIR就是取得項(xiàng)目絕對地址。而MEDIA_URL是指URL訪問時(shí)的URL。例如,
BASE_DIR: /Users/incisor/VSCodeProjects/python/Notes
那么
MEDIA_ROOT:/Users/incisor/VSCodeProjects/python/Notes/media
假設(shè)media目錄下有一張圖片2019.jpg,那么
MEDIA_URL: http://127.0.0.1:8000/media/
然后再通過http://127.0.0.1:8000/media/2019.jpg這個(gè)URL是可以直接訪問這個(gè)圖片的。
IMAGE_ROOT是我自定義的一個(gè)字段,因?yàn)槲蚁胍院罂赡軙蟼饕曨l,或者其他一些文件,想?yún)^(qū)分開,所以我在media目錄下再建了一個(gè)目錄images,那么
IMAGE_ROOT: /Users/incisor/VSCodeProjects/python/Notes/media/images
WEB_HOST_MEDIA_URL是拼接URL時(shí)使用,因?yàn)槲医酉聛硪约浩唇佣鄠€(gè)圖的URL,MEDIA_URL[1:]的原因時(shí)如果不去掉第一個(gè)/,那WEB_HOST_MEDIA_URL會是/media/images/,這顯然不是我們想要的,所以需要把第一個(gè)/去掉。
views.py文件
前端傳過來不定數(shù)量的圖片,可能0張,最多9張,每個(gè)圖片都做base64編碼再傳過來,POST請求里有個(gè)參數(shù)imgs,是一個(gè)數(shù)組,保存base64編碼。
base64編碼如下圖所示,這只是一部分:
前面的data:image/png;base64, 除了后綴會不同,其他的是固定的,所以我會先從這里取得后綴png,再做編碼轉(zhuǎn)換。
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) # 判斷目錄是否存在,不存在則創(chuàng)建
for img in request.data['imgs']:
strs = img.split(',')
suffix = re.findall(r'/(\w+?);', strs[0])[0] # 取得文件后綴
# 拼接服務(wù)器上的文件名
# datetime.now()取得當(dāng)前時(shí)間,精確到了微秒,一般來說是唯一的了,因?yàn)槟夸浭侨掌冢晕募腿サ羧掌?,最后會是一串?dāng)?shù)字
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 # 需要添加這句,包含靜態(tài)資源之類的
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) # 這句不設(shè)置的話,不能通過URL直接訪問到圖片
4、啟動服務(wù),python3 manage.py runserver
5、POST請求,然后返回對應(yīng)的JSON數(shù)據(jù)
{
"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"
}
這樣在數(shù)據(jù)庫方面,就可以直接用一個(gè)varchar類型來存儲多張圖了,前端收到URL串,再按照定好的分隔符[/–sp–/]切開后,就可以顯示了。
以上這篇Django 實(shí)現(xiàn)將圖片轉(zhuǎn)為Base64,然后使用json傳輸就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- 詳解Django自定義圖片和文件上傳路徑(upload_to)的2種方式
- Django實(shí)現(xiàn)前臺上傳并顯示圖片功能
- Django實(shí)現(xiàn)后臺上傳并顯示圖片功能
- Django實(shí)現(xiàn)圖片上傳功能步驟解析
- Django {{ MEDIA_URL }}無法顯示圖片的解決方式
- django 讀取圖片到頁面實(shí)例
- django中的圖片驗(yàn)證碼功能
- django項(xiàng)目登錄中使用圖片驗(yàn)證碼的實(shí)現(xiàn)方法
- Django 實(shí)現(xiàn)前端圖片壓縮功能的方法
- Django 實(shí)現(xiàn)圖片上傳和下載功能
相關(guān)文章
django數(shù)據(jù)庫報(bào)錯(cuò)解決匯總:django.db.utils.OperationalError?1045,1049,
這篇文章主要給大家介紹了關(guān)于django數(shù)據(jù)庫報(bào)錯(cuò)解決:django.db.utils.OperationalError?1045,1049,2003的相關(guān)資料,文中將解決的辦法介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02
Python+pandas數(shù)據(jù)分析實(shí)踐總結(jié)
這篇文章主要介紹了Python+pandas數(shù)據(jù)分析實(shí)踐總結(jié)的相關(guān)資料,需要的朋友可以參考下2023-07-07
零基礎(chǔ)寫python爬蟲之使用Scrapy框架編寫爬蟲
前面的文章我們介紹了Python爬蟲框架Scrapy的安裝與配置等基本資料,本文我們就來看看如何使用Scrapy框架方便快捷的抓取一個(gè)網(wǎng)站的內(nèi)容,隨便選個(gè)小站(dmoz.org)來示例吧2014-11-11
Python argparse命令參數(shù)與config配置參數(shù)示例深入詳解
這篇文章主要介紹了Python argparse命令參數(shù)與config配置參數(shù),argparse是Python內(nèi)置的一個(gè)用于命令項(xiàng)選項(xiàng)與參數(shù)解析的模塊,通過在程序中定義好我們需要的參數(shù),然后在程序啟動命令行傳遞我們想要改變的參數(shù)2023-03-03
簡單了解Python下用于監(jiān)視文件系統(tǒng)的pyinotify包
這篇文章主要介紹了Python下用于監(jiān)視文件系統(tǒng)的pyinotify包,pyinotify基于inotify事件驅(qū)動機(jī)制,需要的朋友可以參考下2015-11-11
使用Python解析FineReport模板數(shù)據(jù)集
這篇文章主要為大家詳細(xì)介紹了如何使用Python解析FineReport模板數(shù)據(jù)集,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解下2023-12-12
解決python 執(zhí)行sql語句時(shí)所傳參數(shù)含有單引號的問題
這篇文章主要介紹了解決python 執(zhí)行sql語句時(shí)所傳參數(shù)含有單引號的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06
如何用 Python 子進(jìn)程關(guān)閉 Excel 自動化中的彈窗
這篇文章主要介紹了如何用 Python 子進(jìn)程關(guān)閉 Excel 自動化中的彈窗,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下2021-05-05

