banner
月落星河Tsukistar

月落星河Tsukistar

浩瀚中的伟大,孤独间的渺小
github
twitter
youtube
bilibili
email

サーバーレス環境下での動的な画像サイズ調整システムの設計と実装

最近の卒業設計のテーマは、以前行ったプロジェクトに基づいており、画像処理に関連しています。サーバーレスも最近数年で人気が出てきたサービスなので、このテーマを選び、ゼロからサーバーレスを研究することにしました。(後記:出題の先生が考え直した結果、私の作業量が少なすぎるとのことで、テーマが大幅に拡張され、今は証明書の認識と処理などを研究することになりました 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 ./を実行して依存関係をダウンロードすることです。

まとめ#

全体のプロセスを通じて、サーバーレスサービスのデプロイ手順を大まかに把握しました。また、サーバーレスの依存関係はコードに付随しているため、開発とデプロイが同じオペレーティングシステムでない場合、コードをアップロードした後にクラウド環境でデプロイすることをお勧めします。そうしないと、実行時エラーが発生する可能性があります。

画像サイズの変更はその中の一つの小さな応用に過ぎず、理論的には多くのアプリケーションがサーバーレス環境で実行され、結果を得ることができます。例えば、短縮リンク、画像認識、文字認識など、今後サーバーレスの応用はますます広がるでしょう。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。