
Amazon Bedrock: Stability AI: 画像生成
Amazon Bedrock: Stability AI: Generate Image
この工程は、Amazon Bedrock 上で動作する Stability AI の モデルを用いて、画像を生成します。
Basic Configs
- 工程名
- メモ
Configs for this Auto Step
- conf_AccessKey
- C1: アクセスキー *
- conf_SecretKey
- C2: シークレットアクセスキー *
- conf_Region
- C3: リージョンコード *
- conf_Model
- C4: モデル *
- conf_Prompt
- C5: プロンプト *#{EL}
- conf_Negative
- C6: ネガティブプロンプト#{EL}
- conf_Seed
- C7: シードを保持している/保存するデータ項目
- conf_Aspect
- C8: 画像アスペクト比 (未設定の場合、1:1)
- conf_Format
- C9: 画像形式 (未設定の場合、PNG)
- conf_File
- C10: 生成されたファイルを追加保存するデータ項目 *
- conf_FileName
- C11: 保存する際のファイル名 *#{EL}
Notes
- アクセスキー、シークレットアクセスキーの作成方法については、Amazon Web Services のドキュメントを参照してください
- 画像生成をサポートしているリージョンは限られます
- 詳細は、Model support by AWS Region in Amazon Bedrock を確認してください
Capture

See Also
Script (click to open)
- 次のスクリプトが記述されている XML ファイルをダウンロードできます
- aws-bedrock-stability-ai-image-generate.xml (C) Questetra, Inc. (MIT License)
- Professional のワークフロー基盤では、ファイル内容を改変しオリジナルのアドオン自動工程として活用できます
const SERVICE = "bedrock";
function main() {
////// == 工程コンフィグ・ワークフローデータの参照 / Config & Data Retrieving ==
const awsKey = configs.getObject("conf_AccessKey").getToken();
const awsSecret = configs.getObject("conf_SecretKey").getToken();
const region = retrieveRegion();
const model = retrieveModel();
const payload = buildPayload();
const fileName = configs.get("conf_FileName");
if (fileName === "") {
throw new Error("File name is blank.");
}
//ファイル名が200文字を超えていないか
if(fileName.length > 200){
throw new Error("File Name should be less than 200 characters");
}
////// == 演算 / Calculating ==
const { generatedFile, seed } = generateImage(awsKey, awsSecret, region, model, payload, fileName);
////// == ワークフローデータへの代入 / Data Updating ==
saveFileData('conf_File', generatedFile);
saveData('conf_Seed', seed);
}
/**
* config からリージョンコードを読み出す
* リージョンコードの形式として不正な場合はエラー
* @return {String}
*/
const retrieveRegion = () => {
const region = configs.get("conf_Region");
// 今後リージョンが増えることも考えて、中央の最大文字数には余裕をみている
const reg = new RegExp("^[a-z]{2}-[a-z]{4,16}-[1-9]$");
if (!reg.test(region)) {
throw new Error("Region Code is invalid.");
}
return region;
}
/**
* config からモデル ID を読み出す
* モデル ID として不正な場合はエラー
* @return {String}
*/
function retrieveModel() {
const model = configs.get('conf_Model');
const reg = new RegExp('^[a-z0-9.:-]+$');
if (!reg.test(model)) {
throw new Error('Model is invalid. It contains an invalid character.');
}
const MODEL_PREFIX = 'stability';
if (!model.startsWith(MODEL_PREFIX)){
throw new Error(`Model is invalid. It must start with "${MODEL_PREFIX}".`);
}
return model;
}
/**
* config から API リクエストのボティにセットするパラメータを読み出し、
* ペイロードを構築する
* @return {Object}
*/
const buildPayload = () => {
const payload = {
prompt: retrieveTextPrompts(),
seed: retrieveSeed()
};
const negative = configs.get('conf_Negative');
if (negative !== '') {
Object.assign(payload, {
negative_prompt: negative
});
}
const aspect = configs.get("conf_Aspect");
if (aspect !== '') {
Object.assign(payload, {
aspect_ratio: aspect
});
}
let format = 'png'
if (configs.get("conf_Format") === 'jpg') {
format = 'jpg'
}
Object.assign(payload, {
output_format: format
});
engine.log(JSON.stringify(payload));
return payload;
}
/**
* config からテキストプロンプトを読み出す
* @return {Array}
*/
const retrieveTextPrompts = () => {
const prompt = configs.get('conf_Prompt');
if (prompt === '') {
throw new Error('Prompt is blank.');
}
return prompt;
};
const MAX_SEED = 4294967295;
/**
* config からシードを読み出す
* @return {Number}
*/
const retrieveSeed = () => {
const seedDef = configs.getObject("conf_Seed");
if (seedDef === null) {
return undefined;
}
const seed = engine.findData(seedDef);
if (seed === null) {
return undefined;
}
const reg = new RegExp('^(0|[1-9][0-9]{0,9})$');
const errorMsg = `Seed must be an integer from 0 to ${MAX_SEED}.`;
if (!reg.test(seed)) {
throw new Error(errorMsg);
}
const seedNum = Number.parseInt(seed);
if (seedNum > MAX_SEED) {
throw new Error(errorMsg);
}
return seedNum;
};
/**
* 画像を生成する API リクエストを送信
* @param awsKey
* @param awsSecret
* @param region
* @param payload
* @param fileName
* @return {Object} {generatedFile: NewQfile, seed: String}
*/
const generateImage = (awsKey, awsSecret, region, model, payload, fileName) => {
const URL = `https://bedrock-runtime.${region}.amazonaws.com/model/${model}/invoke`;
const response = httpClient.begin()
.awsSignV4(awsKey, awsSecret, region, SERVICE)
.body(JSON.stringify(payload), "application/json")
.post(URL);
const status = response.getStatusCode();
const respTxt = response.getResponseAsString();
if (status !== 200) {
engine.log(respTxt);
throw new Error(`Failed to invoke model. status: ${status}`);
}
const responsesBody = JSON.parse(respTxt);
engine.log(JSON.stringify(Object.assign({},responsesBody, { // images 以外の値をログ出力
images: undefined
})));
const image = base64.decodeFromStringToByteArray(responsesBody.images[0]);
let format = "png";
if (payload.output_format === "jpg"){
format = "jpg"
}
const generatedFile = new com.questetra.bpms.core.event.scripttask.NewQfile(
fileName,
`image/${format}`,
image
);
const seed = String(responsesBody.seeds[0])
return { generatedFile, seed };
};
/**
* データ項目への保存
* @param configName
* @param newFile
*/
const saveFileData = (configName, newFile) => {
const def = configs.getObject(configName);
if (def === null) {
return;
}
let files = engine.findData(def);
if (files === null) {
files = new java.util.ArrayList();
}
files.add(newFile);
engine.setData(def, files);
};
/**
* データ項目への保存
* @param configName
* @param data
*/
const saveData = (configName, data) => {
const def = configs.getObject(configName);
if (def === null) {
return;
}
engine.setData(def, data);
};