iOS 18.4の新機能「ImageCreator」で始める動的な画像生成

iOS 18.4の新機能「ImageCreator」で始める動的な画像生成

Clock Icon2025.03.05

iOS 18.4、iPadOS 18.4、Mac Catalyst 18.4、macOS 15.4、visionOS 2.4にて、Image PlaygroundフレームワークにImageCreatorクラスが追加された。本記事ではImageCreatorクラスの使い方を紹介する。

ImageCreatorとは?

WWDC 2024の基調講演で、「Image Playground」が発表された。これは指定したプロンプトとスタイルに基づき画像を生成する機能だ。Image Playgroundは予定より少し遅れて iOS 18.2で公開された。

20250301175002

iOS 18.1 で、UIKit向けに ImagePlaygroundViewController 、SwiftUI向けにView.imagePlaygroundSheetが追加されている。これらは入力されたプロンプトから画像を生成できるViewController/Sheetで、アプリに画像生成機能を組み込むことができる。

https://support.apple.com/ja-jp/guide/iphone/iph0063238b5/ios

しかし、これらのAPIではアプリ独自のカスタマイズが制限されていた。

iOS 18.4で、新たに導入されたImageCreatorクラスで、プログラムによる動的な画像生成ができるようになった。前述のImagePlaygroundViewControllerにはカスタムUIが適用できず、OS組み込みのデザインだったため、アプリによってはそのデザインがマッチしなかったかもしれない。

アプリ独自のデザインで、プログラム的に画像を生成できるようになり、より身近で使いやすくなったといえる。たとえば、SNSアプリでのカスタムスタンプ生成や、ゲームアプリでのキャラクター画像生成など、ユースケースを思いつく。

検証環境

  • macOS Sequoia 15.3.1
  • Xcode 16.3 Beta
  • iOS 18.4 beta1 シミュレータ
    • 注意:iOS 18.4 beta1 シミュレータでは ImageCreatorを利用不可であった。本件に関してはトラブルシューティングの欄に記載した。
  • iPad Pro (第6世代) 12.9インチ / iPad OS 18.4 beta1 (実機)

Apple Intelligence対応のデバイス

ImageCreatorを使用するには、Apple Intelligenceに対応したデバイスが必要である。

Apple Intelligence対応のデバイスについては、Appleのドキュメント「iPhone、iPad、MacでApple Intelligenceを利用するための条件」に書かれている。以下は、2025年3月時点の対応デバイスである。

  • iPhone 16の全モデル
    • iPhone 16 Pro、iPhone 16 Pro Max
    • iPhone 16、iPhone 16 Plus
    • iPhone 16e
  • iPhone 15 Pro、iPhone 15 Pro Max
  • A17 ProまたはM1以降を搭載したiPad全モデル
  • M1以降を搭載したMac

今後発売されるApple A18以降のSoCを搭載したiPhoneでは標準で利用可能になる見込みだ。現時点でApple Intelligence環境を整えるなら、M1搭載iPadが費用対効果が高い選択肢となるだろう。

ImageCreatorを使った画像生成の流れ

ImageCreatorクラスを使用して画像を生成する手順は以下の通りだ。

  1. ImageCreatorインスタンスの生成
    • 非対応デバイスではImageCreator.Error.notSupported例外が発生するため、適切なエラーハンドリングが必要
  2. スタイルの選択
    • availableStylesプロパティを用いてスタイルを選択する。スタイルが選べない場合は処理を中断する
  3. プロンプトやスタイルを指定して画像生成する
    • images(for:style:limit:)メソッドで画像を生成
    • ドキュメントによれば limitパラメータの現在の最大値は4
  4. 生成された画像を受け取る
    • 非同期ストリームを通じて生成された画像を順次処理し、Imageオブジェクトに変換してUIに反映する

コード例

@available(iOS 18.4, *)
private func createImage() async {
	errorText = nil
	isProgress = true
	defer {
		isProgress = false
	}

	do {
		// 1. ImageCreatorインスタンスの生成
		let imageCreator = try await ImageCreator()

		// 2. スタイルの選択
		guard let style = imageCreator.availableStyles.first else {
			errorText = Text("利用可能なスタイルが見つかりません")
			return
		}

		// 3. プロンプトやスタイルを指定して画像生成する
		let generatedImages = imageCreator.images(
			for: [.text("A cat wearing mittens.")],
			style: style,
			limit: 1
		)

		// 4. 生成された画像を受け取る
		for try await image in generatedImages {
			let cgImage = image.cgImage
			let image = Image(cgImage, scale: 1, label: Text("生成された画像です"))

			await MainActor.run {
				images.append(image)
			}
		}
	} catch ImageCreator.Error.notSupported {
		errorText = Text("このデバイスでは画像生成はできません")
	} catch ImageCreator.Error.creationFailed {
		errorText = Text("画像生成に失敗しました")
	} catch {
		errorText = Text("エラー: \(error.localizedDescription)")
	}
}

完全なサンプルコードでは、生成された画像をグリッドレイアウトで表示し、新しい画像生成のためのテキスト入力フィールドとボタンを提供している。参考にしてほしい。

サンプルコードの全体
import ImagePlayground
import SwiftUI

struct ContentView: View {
    @State private var images: [Image] = []
    @State private var prompt = "A cat wearing mittens."
    @State private var errorText: Text? = nil
    @State private var isProgress: Bool = false

    @Environment(\.supportsImagePlayground) private var supportsImagePlayground

    let columns = [GridItem(.adaptive(minimum: 100, maximum: 200))]

    var body: some View {
        if supportsImagePlayground {
            contentView
        } else {
            Text("Apple Intelligence未対応のデバイスです。画像生成はできません")
                .padding()
        }
    }

    var contentView: some View {
        VStack {
            // 生成した画像のリスト
            ScrollView {
                LazyVGrid(columns: columns, alignment: .leading) {
                    ForEach(images.indices, id: \.self) { index in
                        images[index]
                            .resizable()
                            .scaledToFit()
                    }
                }
            }

            Group {
                if isProgress {
                    // 画像生成中はプログレスビューを表示して、ボタンを連打できないようにする
                    ProgressView()
                        .padding()
                } else {
                    if let errorText {
                        errorText
                            .padding()
                    }

                    HStack(alignment: .center) {
                        TextField(text: $prompt) {
                            Text("Enter text")
                        }

                        Button(action: {
                            Task {
                                await createImage()
                            }
                        }) {
                            Text("Generate Images")
                        }
                    }
                }
            }
        }
        .padding()
    }

    @available(iOS 18.4, *)
    private func createImage() async {
        errorText = nil
        isProgress = true
        defer {
            isProgress = false
        }

        do {
            // 1. ImageCreatorインスタンスの生成
            let imageCreator = try await ImageCreator()

            // 2. スタイルの選択
            guard let style = imageCreator.availableStyles.first else {
                errorText = Text("利用可能なスタイルが見つかりません")
                return
            }

            // 3. プロンプトやスタイルを指定して画像生成する
            let generatedImages = imageCreator.images(
                for: [.text(prompt)],
                style: style,
                limit: 1
            )

            // 4. 生成された画像を受け取る
            for try await image in generatedImages {
                let cgImage = image.cgImage
                let image = Image(cgImage, scale: 1, label: Text("生成された画像です"))

                await MainActor.run {
                    images.append(image)
                }
            }
        } catch ImageCreator.Error.notSupported {
            errorText = Text("このデバイスでは画像生成はできません")
        } catch ImageCreator.Error.creationFailed {
            errorText = Text("画像生成に失敗しました")
        } catch {
            errorText = Text("エラー: \(error.localizedDescription)")
        }
    }
}

ImageCreator.Error

ImageCreatorを使用する際に発生するエラー「ImageCreator.Error」を以下に列挙する。

エラーコード 説明
notSupported デバイスが画像生成をサポートしていないことを示すエラー
unavailable 画像生成が現在利用できないことを示すエラー
creationCancelled 親タスクのキャンセルによって発生するエラー
faceInImageTooSmall ソース画像の顔が小さすぎて利用できないことを示すエラー
unsupportedLanguage 入力テキストがサポートされていない言語を使用していることを示すエラー
unsupportedInputImage 指定されたソース画像のいずれかが利用できないことを示すエラー
backgroundCreationForbidden アプリが非表示またはバックグラウンドにいることを示すエラー
creationFailed 画像生成中に一般的な障害が発生したことを示すエラー

特にnotSupportedエラーは、Apple Intelligence非対応デバイスで発生するため、適切なユーザーフィードバックを提供するために必ずハンドリングすべきだ。

トラブルシューティング

ImageCreatorを使用する際に遭遇する可能性のある問題とその解決策について説明する。

iOSシミュレータでの制約について

ImageCreatorはiOSシミュレータでは動作せず、インスタンス生成時にImageCreator.Error.notSupportedエラーが発生する。これは、Apple Intelligence機能が特定のハードウェア(A17 ProまたはM1以降のチップセット)を必要とするためと考えられる。開発・テストには実機が必要だろう。

Apple Intelligenceのモデルのダウンロードが完了しない

Apple Intelligenceを利用するには言語モデルのダウンロードが必要だが、一晩経っても完了しないケースがある。Appleの公式フォーラムによると、地域設定を「United Kingdom」に、言語を「English (UK)」に変更することで解決する場合がある。

手順は以下の通り:

  1. OSの設定アプリを開く
  2. [General]→[Language & Region]→[Region]の順に選択
  3. 「United Kingdom」を選択
  4. [Language]を「English (UK)」に設定

私のiPad Proでも、この設定変更後にモデルのダウンロードが完了した。ただし全てのケースで有効とは限らない点に注意が必要である。

Apple Intelligenceの言語を変えた直後にエラーが発生する

Apple Intelligenceの言語を変更した直後は、新しい言語モデルのダウンロードと適用が必要なため、ImageCreator.Error.unavailableが発生することがある。エラーメッセージは「Image creation is not available at the moment.」であった。しばらく時間をおいてから再試行すると解決する。

ImageCreatorによる画像生成には時間あたりの制限がある?

サンプルコードを書くために何度も画像を生成したが、ImageCreator.Error.creationCancelledImageCreator.Error.creationFailedが発生した。現時点ではAPIの使用制限に関する公式情報はないが、連続的な大量生成には向いていない可能性がある。

まとめ

iOS 18.4のImageCreatorクラスにより、開発者はApple Intelligenceの画像生成機能をプログラム的に利用し、アプリのブランディングに合わせたカスタム体験を提供できるようになった。

現時点では対応デバイスの制限や言語モデルのダウンロード問題など課題もあるが、今後のアップデートでこれらの改善を期待したい。ImageCreatorを活用することで、より魅力的で創造的なアプリ体験を提供できるだろう。

参考

https://developer.apple.com/documentation/imageplayground/imagecreator

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.