概要
S3に格納されているオブジェクト(JPEG画像)をコピーした際に起動するLambda関数。
Lambda関数の処理としては、コピーした画像を読み込んで向きを自動調整し、Exif情報を削除した上でS3にアップロードしている。
環境
go1.16.5を使用。
Lambdaのランタイムは go1.x
。
ソースコード
package main
import (
"bytes"
"errors"
"io"
"log"
"os"
"github.com/disintegration/imaging"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
)
// アップロードされた画像のEXIF情報を削除するのと向きを自動調整し、再アップロードする
func HandleRequest(event events.S3Event) error {
for _, record := range event.Records {
bucket := record.S3.Bucket.Name
key := record.S3.Object.Key
sess := session.Must(session.NewSession(&aws.Config{Region: aws.String("ap-northeast-1")}))
//fileの読み込み
obj, err := s3.New(sess).GetObject(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
if err != nil {
log.Fatal(err)
}
buf, err := io.ReadAll(obj.Body)
if err != nil {
log.Fatal(err)
}
// 向きを自動調整
decoded_image, err := imaging.Decode(bytes.NewReader(buf), imaging.AutoOrientation(true))
if err != nil {
log.Fatalln(err)
}
//コピー先の空ファイル名
// Lambdaでは /tmp/ を付けないとエラーになる
file_name := "/tmp/tmp.jpg"
err = imaging.Save(decoded_image, file_name)
if err != nil {
log.Fatal(err)
}
//imagingで作ったファイルをopen
f, err := os.Open(file_name)
if err != nil {
log.Fatal(err)
}
//S3にアップロード
uploader := s3manager.NewUploader(sess)
_, err = uploader.Upload(&s3manager.UploadInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
Body: f,
})
if err != nil {
log.Fatal(err)
}
}
return nil
}
func main() {
lambda.Start(HandleRequest)
}
ポイント
-
https://github.com/disintegration/imaging の
AutoOrientation
で画像の向きを調整。 -
Lambdaでは一時領域として
/tmp
が提供されていて、画像は/tmp
配下で処理する必要がある。
参考: https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/runtimes-context.html -
ファイルのダウンロード→lambdaで処理→アップロードではなく、ファイルの読み込み→lambdaで処理→アップロードという流れ。
結局Lambdaのストレージを使用しているので、もしかしたら読み込みにした意味はそこまでなかったかも?
最後に
これによって、スマホで撮影したきゃわわなネコチャン🐈の画像が変な向きで表示される...みたいなこともなくなる(はず)。
ちなみにGoは初めて書きました。難しかったです👶