翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
Amazon Rekognition と Lambda を使用して Amazon S3 バケットのアセットにタグを付ける
このチュートリアルでは、Amazon S3 バケットにあるデジタルアセットに自動的にタグ付けする AWS Lambda 関数を作成します。Lambda 関数は、指定された Amazon S3 バケット内のすべてのオブジェクトを読み取ります。バケット内の各オブジェクトについて、イメージを Amazon Rekognition サービスに渡して、一連のラベルを生成します。各ラベルは、イメージに適用されるタグを作成するために使用されます。Lambda 関数を実行すると、指定された Amazon S3 バケット内のすべてのイメージに基づいてタグが自動的に作成され、イメージに適用されます。
例えば、Lambda 関数を実行し、このイメージが Amazon S3 バケット内にあると仮定します。

その後、アプリケーションは自動的にタグを作成し、イメージにそれらを適用します。

注記
このチュートリアルで使用するサービスは、 AWS 無料利用枠の一部です。チュートリアルが終了したら、課金されないように、チュートリアル中に作成したリソースをすべて終了することをお勧めします。
このチュートリアルでは、 AWS SDK for Java バージョン 2 を使用します。追加の Java V2 チュートリアルについては、AWS ドキュメント SDK の例 GitHub リポジトリ
前提条件
開始する前に、AWS 「SDK for Java のセットアップ」の手順を完了する必要があります。次に、以下があることを確認します。
Java 1.8 JDK。
Maven 3.6 以上
ネイチャーイメージが入った Amazon S3 バケット 5-7 これらのイメージは Lambda 関数によって読み取られます。
IAM Lambda ロールを設定する
このチュートリアルでは、Amazon Rekognition および Amazon S3 サービスを使用します。Lambda 関数からこれらのサービスを呼び出すことを可能にするポリシーを持つために、lambda-support ロールを設定する。
ロールを設定するには
にサインイン AWS Management Console し、https://console.aws.amazon.com/iam/
で IAM コンソールを開きます。 -
ナビゲーションペインで、[Roles (ロール)]、[ロールの作成] の順に選択します。
-
[AWS サービス]、[Lambda] の順に選択します。
-
[アクセス許可] タブを選択します。
-
AWSLambdaBasicExecutionRole を検索する。
-
[次のタグ] を選択します。
-
[Review] (レビュー) を選択します。
-
そのロールに lambda-support という名前を付けます。
-
[ロールの作成] を選択します。
-
lambda-support を選択して、概要ページを表示します。
-
[ポリシーのアタッチ] を選択します。
-
ポリシーのリストから [AmazonRekognitionFullAccess] を選択します。
-
Attach policy] (ポリシーのアタッチ) を選択してください。
-
AmazonS3FullAccess を検索してから、添付ポリシー を選択します。
プロジェクトの作成
新しい Java プロジェクトを作成し、必要な設定と依存関係に必須の Maven pom.xml を構成します。pom.xml ファイルが次のようになっていることを確認します。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>WorkflowTagAssets</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>java-basic-function</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.10.54</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.10.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.13.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j18-impl</artifactId> <version>2.13.3</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.6.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.6.0</version> <scope>test</scope> </dependency> <dependency> <groupId>com.googlecode.json-simple</groupId> <artifactId>json-simple</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>rekognition</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.2</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.2</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
コードを書き込む
AWS Lambda ランタイム Java API を使用して、Lambda 関数を定義する Java クラスを作成します。この例では、ハンドラー という名前の Lambda 関数用の Java クラスが 1 つあり、このユースケースには追加のクラスが必要です。次の図は、プロジェクトの Java クラスを示します。すべての Java クラスが、com.example.tags という名前のパッケージに配置されていることに注目してください。

コード用に次の Java クラスを作成します。
ハンドラーは Lambda Java ランタイム API を使用し、この AWS チュートリアルで説明するユースケースを実行します。実行されるアプリケーションロジックは、handleRequest メソッドにあります。
S3Service は、Amazon S3 API を使用して S3 オペレーションを実行します。
AnalyzePhotos では、Amazon Rekognition API を使用してイメージを分析します。
バケット項目 は、Amazon S3 バケット情報を格納するモデルを定義します。
作業項目 は Amazon Rekognition データを格納するモデルを定義します。
ハンドラークラス
この Java コードは、Handler のクラスを表します。そのクラスは、Lambda 関数に渡されるフラグを読み取ります。s3Service.listBucketObjects メソッドは、各要素がオブジェクトキーを表す文字列値である リスト オブジェクトを返します。フラグの値が true の場合、リストを繰り返し処理し、s3Service.tagAssets メソッドを呼び出して、タグを各オブジェクトに適用することで、タグが適用されます。フラグの値が false の場合、タグを削除する s3Service.DeleteTagfromObject のメソッドが呼び出されます。また、LambdaLogger オブジェクトを使用して、Amazon CloudWatch のログにメッセージを記録できることに注目してください。
注記
バケット名をbucketName 変数に指定することを確認してください。
package com.example.tags; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.LambdaLogger; import java.util.ArrayList; import java.util.List; import java.util.Map; public class Handler implements RequestHandler<Map<String,String>, String> { @Override public String handleRequest(Map<String, String> event, Context context) { LambdaLogger logger = context.getLogger(); String delFlag = event.get("flag"); logger.log("FLAG IS: " + delFlag); S3Service s3Service = new S3Service(); AnalyzePhotos photos = new AnalyzePhotos(); String bucketName = "<Enter your bucket name>"; List<String> myKeys = s3Service.listBucketObjects(bucketName); if (delFlag.compareTo("true") == 0) { // Create a List to store the data. List<ArrayList<WorkItem>> myList = new ArrayList<>(); // loop through each element in the List and tag the assets. for (String key : myKeys) { byte[] keyData = s3Service.getObjectBytes(bucketName, key); // Analyze the photo and return a list where each element is a WorkItem. ArrayList<WorkItem> item = photos.detectLabels(keyData, key); myList.add(item); } s3Service.tagAssets(myList, bucketName); logger.log("All Assets in the bucket are tagged!"); } else { // Delete all object tags. for (String key : myKeys) { s3Service.deleteTagFromObject(bucketName, key); logger.log("All Assets in the bucket are deleted!"); } } return delFlag; } }
S3 サービスクラス
次のクラスは、Amazon S3 API を使用して S3 オペレーションを実行します。例えば、getObjectBytes メソッドは、イメージを表すバイト配列を返します。同様に、listBucketObjects メソッドは、各要素がキー名を指定する文字列値である リスト オブジェクトを返します。
package com.example.tags; import software.amazon.awssdk.core.ResponseBytes; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.model.GetObjectRequest; import software.amazon.awssdk.services.s3.model.PutObjectTaggingRequest; import software.amazon.awssdk.services.s3.model.GetObjectResponse; import software.amazon.awssdk.services.s3.model.S3Exception; import software.amazon.awssdk.services.s3.model.ListObjectsResponse; import software.amazon.awssdk.services.s3.model.S3Object; import software.amazon.awssdk.services.s3.model.GetObjectTaggingResponse; import software.amazon.awssdk.services.s3.model.ListObjectsRequest; import java.util.ArrayList; import java.util.List; import software.amazon.awssdk.services.s3.model.Tagging; import software.amazon.awssdk.services.s3.model.Tag; import software.amazon.awssdk.services.s3.model.GetObjectTaggingRequest; import software.amazon.awssdk.services.s3.model.DeleteObjectTaggingRequest; public class S3Service { private S3Client getClient() { Region region = Region.US_WEST_2; return S3Client.builder() .region(region) .build(); } public byte[] getObjectBytes(String bucketName, String keyName) { S3Client s3 = getClient(); try { GetObjectRequest objectRequest = GetObjectRequest .builder() .key(keyName) .bucket(bucketName) .build(); // Return the byte[] from this object. ResponseBytes<GetObjectResponse> objectBytes = s3.getObjectAsBytes(objectRequest); return objectBytes.asByteArray(); } catch (S3Exception e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return null; } // Returns the names of all images in the given bucket. public List<String> listBucketObjects(String bucketName) { S3Client s3 = getClient(); String keyName; List<String> keys = new ArrayList<>(); try { ListObjectsRequest listObjects = ListObjectsRequest .builder() .bucket(bucketName) .build(); ListObjectsResponse res = s3.listObjects(listObjects); List<S3Object> objects = res.contents(); for (S3Object myValue: objects) { keyName = myValue.key(); keys.add(keyName); } return keys; } catch (S3Exception e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return null; } // Tag assets with labels in the given list. public void tagAssets(List myList, String bucketName) { try { S3Client s3 = getClient(); int len = myList.size(); String assetName = ""; String labelName = ""; String labelValue = ""; // Tag all the assets in the list. for (Object o : myList) { // Need to get the WorkItem from each list. List innerList = (List) o; for (Object value : innerList) { WorkItem workItem = (WorkItem) value; assetName = workItem.getKey(); labelName = workItem.getName(); labelValue = workItem.getConfidence(); tagExistingObject(s3, bucketName, assetName, labelName, labelValue); } } } catch (S3Exception e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } // This method tags an existing object. private void tagExistingObject(S3Client s3, String bucketName, String key, String label, String LabelValue) { try { // First need to get existing tag set; otherwise the existing tags are overwritten. GetObjectTaggingRequest getObjectTaggingRequest = GetObjectTaggingRequest.builder() .bucket(bucketName) .key(key) .build(); GetObjectTaggingResponse response = s3.getObjectTagging(getObjectTaggingRequest); // Get the existing immutable list - cannot modify this list. List<Tag> existingList = response.tagSet(); ArrayList<Tag> newTagList = new ArrayList(new ArrayList<>(existingList)); // Create a new tag. Tag myTag = Tag.builder() .key(label) .value(LabelValue) .build(); // push new tag to list. newTagList.add(myTag); Tagging tagging = Tagging.builder() .tagSet(newTagList) .build(); PutObjectTaggingRequest taggingRequest = PutObjectTaggingRequest.builder() .key(key) .bucket(bucketName) .tagging(tagging) .build(); s3.putObjectTagging(taggingRequest); System.out.println(key + " was tagged with " + label); } catch (S3Exception e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } // Delete tags from the given object. public void deleteTagFromObject(String bucketName, String key) { try { DeleteObjectTaggingRequest deleteObjectTaggingRequest = DeleteObjectTaggingRequest.builder() .key(key) .bucket(bucketName) .build(); S3Client s3 = getClient(); s3.deleteObjectTagging(deleteObjectTaggingRequest); } catch (S3Exception e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }
AnalyzePhotos クラス
次の Java コードは、AnalyzePhotos のクラスを表します。このクラスは Amazon Rekognition API を使用して、イメージを分析します。
package com.example.tags; import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider; import software.amazon.awssdk.core.SdkBytes; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.rekognition.RekognitionClient; import software.amazon.awssdk.services.rekognition.model.Image; import software.amazon.awssdk.services.rekognition.model.DetectLabelsRequest; import software.amazon.awssdk.services.rekognition.model.DetectLabelsResponse; import software.amazon.awssdk.services.rekognition.model.Label; import software.amazon.awssdk.services.rekognition.model.RekognitionException; import java.util.ArrayList; import java.util.List; public class AnalyzePhotos { // Returns a list of WorkItem objects that contains labels. public ArrayList<WorkItem> detectLabels(byte[] bytes, String key) { Region region = Region.US_EAST_2; RekognitionClient rekClient = RekognitionClient.builder() .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .region(region) .build(); try { SdkBytes sourceBytes = SdkBytes.fromByteArray(bytes); // Create an Image object for the source image. Image souImage = Image.builder() .bytes(sourceBytes) .build(); DetectLabelsRequest detectLabelsRequest = DetectLabelsRequest.builder() .image(souImage) .maxLabels(10) .build(); DetectLabelsResponse labelsResponse = rekClient.detectLabels(detectLabelsRequest); // Write the results to a WorkItem instance. List<Label> labels = labelsResponse.labels(); ArrayList<WorkItem> list = new ArrayList<>(); WorkItem item ; for (Label label: labels) { item = new WorkItem(); item.setKey(key); // identifies the photo. item.setConfidence(label.confidence().toString()); item.setName(label.name()); list.add(item); } return list; } catch (RekognitionException e) { System.out.println(e.getMessage()); System.exit(1); } return null ; } }
バケット項目のクラス
次の Java コードは、Amazon S3 オブジェクトデータを格納する バケット項目 のクラスを表します。
package com.example.tags; public class BucketItem { private String key; private String owner; private String date ; private String size ; public void setSize(String size) { this.size = size ; } public String getSize() { return this.size ; } public void setDate(String date) { this.date = date ; } public String getDate() { return this.date ; } public void setOwner(String owner) { this.owner = owner ; } public String getOwner() { return this.owner ; } public void setKey(String key) { this.key = key ; } public String getKey() { return this.key ; } }
作業項目のクラス
次の Java コードは、作業項目 のクラスを表します。
package com.example.tags; public class WorkItem { private String key; private String name; private String confidence ; public void setKey (String key) { this.key = key; } public String getKey() { return this.key; } public void setName (String name) { this.name = name; } public String getName() { return this.name; } public void setConfidence (String confidence) { this.confidence = confidence; } public String getConfidence() { return this.confidence; } }
プロジェクトをパッケージ化する
次の Maven コマンドを使用して、プロジェクトを.jar (JAR) ファイルにパッケージ化します。
mvn package
JAR ファイルは、ターゲット フォルダ (プロジェクトフォルダの子フォルダ) の中にあります。

注記
プロジェクトの POM ファイル内にある maven-shade-plugin の使用に注目してください。このプラグインは、必要な依存関係を含む JAR を作成する役割を担います。このプラグインなしでプロジェクトをパッケージ化しようとすると、必要な依存関係が JAR ファイル内に含まれず、ClassNotFoundException に直面します。
Lambda 関数をデプロイします。
Lambdaのコンソール
を開きます。 [関数を作成] を選択します。
Author from scratch (製作者を最初から) を選択します。
基本的な情報 セクションに、名前として cron と入力します。
[Runtime] で、[Java 8] を選択します。
[Use an existing role (既存のロールの使用)] を選択し、lambda-support (作成した IAM ロール) を選択します。
[関数を作成] を選択します。
[コードエントリタイプ] で、[.ZIP またはファイルをアップロード] を選択します。
アップロード を選択し、作成した JAR ファイルを参照します。
ハンドラー を使用する場合、関数の完全修飾名を入力します。例えば、com.example.tags.Handler:handleRequest (com.example.tags はパッケージを指定し、ハンドラー は :: およびメソッド名が続くクラスです)。
[Save] を選択します。
Lambda メソッドをテストする
チュートリアルのこの時点で、Lambda 関数をテストできます。
Lambda コンソールで、Test タブをクリックし、次の JSON を入力します。
{ "flag": "true" }
注記
true を送るとデジタルアセットにタグを付け、false を送るとタグを削除します。
[呼び出し ボタンを選択します。Lambda 関数が呼び出されると、成功したメッセージが表示されます。
これで、Amazon S3 バケットにあるディフィラルアセットにタグを自動的に適用する AWS Lambda 関数が作成されました。このチュートリアルの冒頭で説明したように、必ずこのチュートリアルの実行中に作成したリソースをすべて終了し、課金されないようにしてください。
その他の AWS マルチサービスの例については、AWS 「Documentation SDK examples GitHub repository