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

除另有声明外,本博客文章均采用 知识共享(Creative Commons) 署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可,转载请注明文章出处。