最近の卒業設計のテーマは、以前行ったプロジェクトに基づいており、画像処理に関連しています。サーバーレスも最近数年で人気が出てきたサービスなので、このテーマを選び、ゼロからサーバーレスを研究することにしました。(後記:出題の先生が考え直した結果、私の作業量が少なすぎるとのことで、テーマが大幅に拡張され、今は証明書の認識と処理などを研究することになりました QwQ)
参考記事:【AWS 征文】AWS Serverless アーキテクチャを使用して画像サイズを動的に調整する
開発環境#
Python 3.6(Tencent Cloud は現在 Python 3 のこのバージョンのみをサポートしています)、Tencent Cloud SCF
手順#
環境設定#
Tencent Cloud の「Serverless Framework」で新しい Flask フレームワークを作成し、名前と地域は適当に入力します。以下の図のように:
デプロイが完了したら、「開発デプロイ」の中で「コードを更新」をクリックします:
その後、ローカル開発を選択してプロジェクトをダウンロードします:
(実際には「クラウド関数 - 関数サービス - 新しく作成した関数を選択 - 関数コード」の部分でコードを修正したり新しいファイルを追加したりする方が便利で、環境の一貫性が保たれますが、上記の方法はローカルでのデバッグと修正が容易で、それぞれ利点と欠点があります)
これで基本的なフレームワークが整いました。
機能開発#
現在、関数が処理して返すことができる画像は私のクラウドストレージに保存されており、主に呼び出しやパラメータの予約のためです。Flask アプリの固有の形式を利用して、screen_width(画面幅)と pic_url(画像パス)の 2 つのパラメータを予約しました。
呼び出す際に画面幅を指定すると、対応する幅で等比縮小された画像が返されます:
指定しない場合は元の画像が返されます:
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 ./
を実行して依存関係をダウンロードすることです。
まとめ#
全体のプロセスを通じて、サーバーレスサービスのデプロイ手順を大まかに把握しました。また、サーバーレスの依存関係はコードに付随しているため、開発とデプロイが同じオペレーティングシステムでない場合、コードをアップロードした後にクラウド環境でデプロイすることをお勧めします。そうしないと、実行時エラーが発生する可能性があります。
画像サイズの変更はその中の一つの小さな応用に過ぎず、理論的には多くのアプリケーションがサーバーレス環境で実行され、結果を得ることができます。例えば、短縮リンク、画像認識、文字認識など、今後サーバーレスの応用はますます広がるでしょう。