Unityで画像をS3にアップロードしてQRコードを生成する
はじめに
ARアプリで撮影した写真をAmazon S3にアップロードして画像のURLをQRコード表示するサンプルを作ってみた。
展示会などでARアプリを体験してくれた人達に記念撮影した写真のデータを渡せるような仕組みが欲しいと思ったので作った。
主な実装
それぞれの実装方法は調べれば情報が出てくるけど、「スクリーンショット取得 ⇒ S3に画像アップロード ⇒ URLのQRコードを生成」という一覧の流れがまとまってるものは見つからなかった。
スクリーンショットを取得する
PhotoUploadPresenter.cs の一部抜粋
private void TakePhoto() { StartCoroutine(TakePhotoCoroutine()); } IEnumerator TakePhotoCoroutine() { _IsPreview = true; yield return new WaitForEndOfFrame(); // Read pixels from screen(currently active RenderTexture) into the saved texture data. Texture2D preview = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false, false); preview.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0); preview.Apply(); _PhotoPreview.texture = preview; _PhotoPreviewUIRoot.SetActive(true); }
S3に画像データをアップロードする
PhotoUploadPresenter.cs の一部抜粋
以下のコードの「_StorageClient」は
S3Storage.cs
のインスタンス
private async void OnClickSaveImage() { Texture2D tex2d = _PhotoPreview.texture as Texture2D; byte[] pngData = tex2d.EncodeToPNG(); MemoryStream memoryStream = new MemoryStream(pngData); string dateTimeStr = DateTime.Now.ToString("yyyyMMddHHmmss"); string filename = "Photo_" + dateTimeStr + ".png"; var response = await _StorageClient.PubObjectAsync(_BucketName, filename, memoryStream, S3CannedACL.PublicRead); Debug.Log("Response: " + response.HttpStatusCode); if (response.HttpStatusCode == HttpStatusCode.OK) { string url = _StorageClient.GetPublicUrl(_BucketName, filename); _Qrcode.texture = QRCodeGenerator.GenerateQRCodeTexture(url, 256, 256); _PhotoPreviewUIRoot.SetActive(false); _QRCodeUIRoot.SetActive(true); } else { Debug.LogError("Response: " + response.HttpStatusCode); } }
QRコードを生成する
using UnityEngine; using ZXing; using ZXing.QrCode; namespace PhotoUploader { public class QRCodeGenerator { public static Texture2D GenerateQRCodeTexture(string text, int width, int height) { Texture2D qrTex = new Texture2D(width, height); Color32[] pixels = Encode(text, width, height); qrTex.SetPixels32(pixels); qrTex.Apply(); return qrTex; } public static Color32[] Encode(string text, int width, int height) { var writer = new BarcodeWriter { Format = BarcodeFormat.QR_CODE, Options = new QrCodeEncodingOptions { Height = height, Width = width } }; return writer.Write(text); } } }
サンプルを動かすまでの流れ
AWSの準備
- S3のバケット作成
- CognitoのIDプール作成
- IAMのポリシー作成・設定
Unityプロジェクトの準備
- AWSConfigs作成
- AWSConfigsとバケット名の設定
Unityアプリの実行
注意点
ポリシー作成・設定
- 画像アップロード先のバケットに対して、オブジェクトをアップロードする操作(PubObject)とアクセス権を設定する操作(PutObjectACL)を許可するポリシーが必要
サンプル
iOS向けのビルド
- iOS向けにビルドして実行するためには、必要なライブラリをlink.xmlに記載する必要がある(※サンプルプロジェクトには既に含まれている)
参考:AWS SDK for .NETを使うUnityアプリをiOS/Android向けにビルドする
サンプルを動かすまでの流れ(詳細)
AWSの準備
S3のバケット作成
公開可能な設定にしておく
CognitoのIDプール作成
認証されていないIDにチェックを入れる
⇒ ユーザーIDとパスワードによる認証をしなくてもUnityアプリからS3を操作できるようにするため
デフォルトだとロールを新規作成するので、そのままでOK
IAMのポリシー作成・設定
CognitoのIDプール作成時に新しく作られたロールに対して、S3を操作するためのポリシーを作成してアタッチする
ポリシーの新規作成
画像アップロード先のバケットに対して、オブジェクトをアップロードする操作(PubObject)とアクセス権を設定する操作(PutObjectACL)を許可するポリシーが必要なので、最終的には以下のようになった。
CognitoのIDプール作成時に新しく作られたロールにアタッチする
Unityプロジェクトの準備
AWSConfigs作成
AWSConfigsというScriptableObjectで設定値を管理するようにしている。
リージョン名・IDプールのIDを設定する
AWSConfigsとバケット名の設定
作成したAWSConfigsをセットする。対象のバケット名も指定する。
Unityアプリの実行
おわりに
展示会などでARアプリを体験してくれた人達に記念撮影した写真のデータを渡せるような仕組みが欲しいと思って作ったので、今後色々と活用していきたい。