最近毕业设计选题,基于我之前做过的项目和图像处理有关,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 的应用会愈发广泛。