最近畢業設計選題,基於我之前做過的項目和圖像處理有關,serverless 也是最近幾年開始流行的一種服務,於是選擇這個題目,從零開始研究 serverless。(後記:出題老師後來想了想我這個的工作量太小了,所以把題目擴充了許多,現在要去研究證件識別和處理之類的了 QwQ)
參考文章:【AWS 徵文】使用 AWS Serverless 架構動態調整圖片大小
開發環境#
Python 3.6(腾讯云對於 Python 3 目前只支持這個版本),腾讯云 SCF
步驟#
配置環境#
在腾讯云的 “Serverless Framework” 中新建一個 Flask 框架,名稱和地區隨便填,如下圖:
部署完成後在 “開發部署” 中點擊 “更新代碼”:
隨後選擇本地開發將項目下載下來:
(其實更便捷的地方在 “雲函數 - 函數服務 - 選擇新建的那個函數 - 函數代碼” 處修改代碼或者新增文件,可以保證環境的一致性,但是上面的方法便於本機調試與修改,各有利弊)
至此,基本框架已經搭好了。
功能開發#
目前函數能夠處理並返回的圖片存放於我的雲存儲,主要是便於調用和預留參數。利用 Flask app 的固有格式,預留了 screen_width(屏幕寬度)和 pic_url(圖片路徑)兩個參數。
在調用時,指定屏幕寬度則返回對應寬度等比縮放的圖片:
不指定則返回原圖:
在 Flask 部分代碼如下:
@app.route("/pic/<pic_url>")
def source_picture(pic_url):
img_src = "存儲空間地址" + pic_url
# 相當於把一張圖片讀入再讀出,圖片大小會變得小一些
response = make_response(picture.image_output(picture.image_input(img_src)))
# 設置response的headers對象
response.headers['Content-Type'] = 'image/jpeg'
return response
@app.route("/pic/<screen_width>/<pic_url>")
def picture_url_get(screen_width, pic_url):
# 避免數據類型錯誤
width = int(screen_width)
img_src = "存儲空間地址" + pic_url
# 創建response對象
response = make_response(picture.image_output(picture.image_resize(width, img_src)))
# 設置response的headers對象
response.headers['Content-Type'] = 'image/jpeg'
return response
主要使用了 make_response 來創建 response 對象包裝圖片,並返回到瀏覽器,避免先存儲再訪問存儲好的圖片。
對於圖片處理部分:
image_input 函數使用 requests 從 URL 獲取圖片,封裝成 response 對象,隨後用 PIL 的 Image 庫打開,注意 response 對象要用 BytesIO 處理:
def image_input(img_src):
response = requests.get(img_src, headers=headers)
image = Image.open(BytesIO(response.content))
return image
image_output 函數使用 BytesIO 將圖片轉換為字節流,保存後返回:
def image_output(image):
img_byte = BytesIO()
image.save(img_byte, format="JPEG")
img_byte = img_byte.getvalue()
return img_byte
image_resize 函數使用了 Image 裡的 resize 方法,將圖片進行等比縮放,其中 Image.ANTIALIAS 是高清晰度的參數:
def image_resize(width, img_src):
image = image_input(img_src)
resize = image.resize((width, int(image.size[1] * width / image.size[0])), Image.ANTIALIAS)
return resize
遇到的問題與解決方案#
npm 安裝時遇到 rollbackFailedOptional: verb npm-session 問題#
使用npm install -g cnpm --registry=https://registry.npm.taobao.org
命令,用淘寶源替換官方源,隨後使用 cnpm 進行安裝。
安裝相應第三方庫報錯#
可以使用阿里鏡像:https://mirrors.aliyun.com/pypi/simple/ ,同時serverless.yml
文件中 pip 的相關代碼改為hook: pip install -i https://mirrors.aliyun.com/pypi/simple/ -r requirements.txt -t ./
Pillow 的 import 錯誤#
原因為本地環境與雲端環境不一致,即使均為 Python 3.6.0 版本,Windows 上與 Linux 上的第三方庫也有細微的不同。解決方法為將代碼上傳後,在雲端執行pip install -i https://mirrors.aliyun.com/pypi/simple/ -r requirements.txt -t ./
下載依賴。
總結#
整個流程下來自己大致摸清了部署 serverless 服務的步驟,同時也意識到由於 serverless 的依賴都是隨著代碼附帶的,若開發和部署不是同一個操作系統,建議在代碼上傳後於雲環境中進行部署,以免發生運行時的錯誤。
圖片大小的改變只是其中的一個小應用,理論上來講許多應用都可以在 serverless 環境下運行並得出結果,例如短鏈接、圖像識別、文字識別等等,未來 serverless 的應用會愈發廣泛。