上一篇介紹了環境的搭建,這一篇介紹開發細節。主要包括兩方面,調用Google Cloud Vision API 分析圖片微信小程序圖片上傳。分析圖片(通過Vision API實現)之前已經配置好了調用API的環 ...
上一篇介紹了環境的搭建,這一篇介紹開發細節。主要包括兩方面,
之前已經配置好了調用API的環境,現在就來編寫代碼調用API。
# detect_labels.py
from google.cloud import vision
# 分成兩個函數是為了給django調用做準備。
def call_vision_api(f): # django調用此函數
vision_client = vision.Client()
image = vision_client.image(content=f.read())
labels = image.detect_labels()
label_list = [label.description for label in labels]
return label_list
def detet_image(file_name):
with open(file_name, 'rb') as f:
return call_vision_api(f)
if __name__ == '__main__':
print(detet_image('test.jpg'))
詳細說明見Google Cloud Vision API文檔和Python Using the Vision API
這里分為兩部分:
首先我先從服務端的接收接口開始介紹。
現在我們的建立的django項目的目錄結構
wxbackground/
├── db.sqlite3
├── manage.py
└── wxbackground
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
首先在wxbackground/wxbackground/目錄下建立views.py。因為微信小程序上傳是是發送的POST情況,所以我們的view.py里面也應該接收POST請求。view.py中代碼如下。
# view.py
from django.http import HttpResponse
def upload(request):
if request.method == 'POST': # 判斷是否是POST類型
return HttpResponse('This is POST!') # 測試
else:
return HttpResponse('Hello world!') # 測試
同時需要修改同一目錄下的urls.py文件,這個是django的路由,通過在這個文件中配置才能正確的訪問到目標函數。urls.py代碼如下:
# urls.py
from django.conf.urls import url
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^admin/', admin.site.urls), # 這是管理界面
url(r'^test/', views.upload), # 這是剛才添加的函數
]
配置完成后在manage.py路徑下輸入
$:python3 manage.py runserver 0.0.0.0:8000
在瀏覽器中輸入云虛擬機ip:8000/upload/測試是否配置完成,若配置ok則瀏覽器頁面會顯式“Hello world!”。
在views.py編寫接收文件代碼,并調用之前寫的圖片分析函數。首先將剛才編寫的detect_labels.py放入當前目錄下。
由于我們并不想保存上傳的圖片,所以我們直接將上傳圖片流再上傳到谷歌API中檢測。
view.py中代碼如下:
# view.py
from django.http import HttpResponse
from . import detect_labels
def upload(request):
if request.method == 'POST': # 判斷是否是POST類型
img = request.FILES.get('picture') # 微信小程序上傳時‘name’字段命名為‘picture’
if img is None:
return HttpResponse('You need upload a picture!')
# 下面調用剛才寫好的call_vision_api函數,然后將返回的結果轉換為字符串,返回給微信小程序。
labels = detect_labels.call_vision_api(img)
return HttpResponse(str(labels))
else:
return HttpResponse('Hello world!') # 測試
這里說明一下,在django中,從FILES.get('picture')
得到的文件類型為InMemoryUploadedFile
類型,通過調用其read()
函數,獲得圖片IO
流。而Vision API需要的也是IO
流,所以程序中直接將InMemoryUploadedFile
作為call_vision_api
函數的輸入不會發生類型錯誤。
在配置上傳之前,需要先在微信公眾平臺官網中,將域名添加到添加uploadFile合法域名。可以參看微信小程序 wx.request合法域名配置詳解。
微信小程序上傳需要兩個步驟:
在微信小程序API中wx.uploadFile(OBJECT)這里其實已經介紹得很清楚了。
我的上傳代碼index.js如下:
const uploadFileUrl = 'https://yoursite/upload/' # yoursite是你申請的域名。
Page({
data: {
imageSrc: null,
},
chooseImage: function () { //綁定的chooseImage控件
var that = this
wx.chooseImage({ // 選定圖片
sourceType: ['camera', 'album'],
sizeType: ['compressed'], //這里選擇壓縮圖片
count: 1,
success: function (res) {
console.log(res)
that.setData({
imageSrc: res.tempFilePaths[0]
})
}
})
},
check: function (e) { // 綁定的check button
var that = this
wx.uploadFile({ // 上傳圖片
url: uploadFileUrl,
name: 'picture',
filePath: that.data.imageSrc,
formData: {
'user': 'test'
},
success: function (res) {
console.log('imageSrc is:', that.data.imageSrc)
console.log('uploadImage success, res is:', res)
wx.showModal({
title: "圖片詳情",
content: res.data,
showCancel: false,
confirmText: "確定"
})
},
fail: function ({errMsg}) {
console.log('uploadImage fail, errMsg is', errMsg)
}
})
},
reload: function (e) { // 綁定的reload button
this.setData({
imageSrc: null
})
}
})
微信小程序界面布局index.wxml如下:
<view class="container">
<view class="page-body">
<view class="page-section">
<view class="page-body-info">
<block wx:if="{{imageSrc}}">
<view class="weui-uploader__files">
<view class="weui-uploader__file">
<image class="weui-uploader__img" src="{{imageSrc}}"></image>
</view>
</view>
</block>
<block wx:else>
<view class="image-plus image-plus-nb" bindtap="chooseImage">
<view class="image-plus-horizontal"></view>
<view class="image-plus-vertical"></view>
</view>
<view class="image-plus-text">選擇圖片</view>
</block>
</view>
<view class="body-view">
<button type="default" bindtap="check">檢測</button>
</view>
<view class="body-view">
<button type="default" bindtap="reload">重置</button>
</view>
</view>
</view>
</view>
這里有個小坑,注意一下:微信小程序在電腦上開發時,wx.chooseImage
中的sizeType: ['compressed']
不會生效,只有在微信上調用小程序時才會生效。
現在服務端與微信小程序已經搭建完畢,現在我們就可以測試是否能夠上傳成功。完結撒花。