WWDC Quick Look 💓 By SwiftGGTeam
Image Playground で高品質な画像を作成する

Image Playground で高品質な画像を作成する

元の動画を見る

ハイライト

Apple は Image Playground の生成モデルを Private Cloud Compute に移行しました。これにより、開発者は App に高品質な画像生成を統合でき、写実的なスタイル、複数サイズ、カスタムスタイル、写真や描画を使ったビジュアル参照に対応できます。

主要内容

これまで App に AI 画像生成を統合するには、API キーの申請、サーバー設定、使用量制限の管理、スタイル選択 UI の構築、ユーザーのプライバシー懸念への対応など、多くの複雑な問題を扱う必要がありました。技術に詳しくないユーザーは、自分が欲しい画像をどう説明すればよいか分からないこともよくあります。

Apple はこれらの機能を ImagePlayground フレームワークとしてまとめました。この体験は Messages や Freeform などのシステム App ですでに検証されており、ユーザーにもなじみがあります。開発者はビュー修飾子を1つ追加するだけで、完全な画像生成 UI を利用できます。

生成モデルは Private Cloud Compute 上で動作するようになりました。これにより画像品質が大きく向上し、真に写実的な写真スタイルの画像も生成できます。同時に、ユーザーデータは保存も共有もされません。開発者から見ると、保守するサーバーはなく、使用量制限もシステムが自動管理します。

詳細

00:00 フレームワーク概要

Image Playground フレームワークは iOS、iPadOS、macOS、visionOS をサポートし、Apple Intelligence 対応デバイスが必要です。画像生成は Apple の Private Cloud Compute 上で行われ、ユーザーデータは保存も共有もされません。

このフレームワークは、テキスト説明からの画像生成、複数人物のシーン、アニメーション、イラスト、スケッチ、Genmoji などの複数プリセットスタイル、横長、縦長、正方形などの複数サイズとアスペクト比、写真ライブラリからの人物インポート、既存画像やスケッチをもとにした生成を提供します。

05:28 SwiftUI 統合

SwiftUI で Image Playground を採用するには、ビュー修飾子を1つ追加するだけです。

// SwiftUI で Image Playground を採用する

@State private var showingPlayground = false

var body: some View {
    Button("画像を作成") {
        showingPlayground = true
    }
    .imagePlaygroundSheet(
        isPresented: $showingPlayground,
        onCompletion: { url in
            var updated = currentCard
            store.saveImage(url, for: &updated)
        }
    )
}

重要な点:

  • isPresented は sheet の表示を制御する Binding<Bool> です。
  • onCompletion コールバックは生成された画像の URL を返します。この URL は App コンテナ内の一時的な場所を指します。
  • セッションが終了する前に、画像を別の場所へ保存する必要があります。

06:29 コンテキストの種

sheet に初期コンテキストを渡すことで、ユーザーが空白から始めなくてよくなります。

// カードのコンテキストで sheet に初期値を与える

var concepts: [ImagePlaygroundConcept] {
    [
        .text(card.theme),
        .extracted(from: card.message, title: card.theme),
    ]
}

var body: some View {
    Button("画像を作成") {
        showingPlayground = true
    }
    .imagePlaygroundSheet(
        isPresented: $showingPlayground,
        concepts: concepts,
        onCompletion: { url in
            var updated = card
            store.saveImage(url, for: &updated)
        }
    )
}

重要な点:

  • .text() はテキスト説明をそのまま包みます。
  • .extracted() は長いテキストから最も関連する概念を抽出します。
  • sheet に渡すと、プロンプト入力欄に自動で反映されます。

07:11 参照画像をもとに生成する

画像をビジュアル参照として渡すことができます。

// 参照写真から始める

@State private var sourceImage: Image?

var body: some View {
    Button("画像を作成") {
        showingPlayground = true
    }
    .imagePlaygroundSheet(
        isPresented: $showingPlayground,
        concepts: concepts,
        sourceImage: sourceImage,
        onCompletion: { url in
            var updated = card
            store.saveImage(url, for: &updated)
        }
    )
}

重要な点:

  • sourceImage は任意の SwiftUI Image を受け取ります。
  • 画像は視覚的なインスピレーションとして使われ、ユーザーは sheet 内で置き換えたり調整したりできます。
  • ユーザーが写真ライブラリから写真を選び、それを起点にしたい場面に適しています。

07:42 スケッチをもとに生成する

PencilKit と組み合わせると、スケッチで生成を導けます。

// 描画を使って視覚的な提案を渡す

@State private var drawing = PKDrawing()

var concepts: [ImagePlaygroundConcept] {
    var result: [ImagePlaygroundConcept] = [
        .text(card.theme),
        .extracted(from: card.message)
    ]
    if !drawing.strokes.isEmpty {
        result.append(.drawing(drawing))
    }
    return result
}

重要な点:

  • .drawing() は PencilKit の PKDrawing を受け取ります。
  • ストロークは視覚的な提案として構図を導きますが、結果を固定するわけではありません。
  • iPad で手描き体験を提供する App に適しています。

08:06 UIKit/AppKit 統合

UIKit と AppKit では ImagePlaygroundViewController を使います。

// UIKit または AppKit で Image Playground を採用する

func presentViewController() {
    let viewController = ImagePlaygroundViewController()
    viewController.concepts = [
        .text(card.theme),
        .extracted(from: card.message)
    ]
    viewController.delegate = self
    present(viewController, animated: true)
}

func imagePlaygroundViewController(
    _ viewController: ImagePlaygroundViewController,
    didCreateImageAt url: URL
) {
    var updated = card
    store.saveImage(url, for: &updated)
    dismiss(animated: true)
}

重要な点:

  • 表示前に concepts プロパティを設定します。
  • delegate パターンで結果を受け取ります。
  • API は SwiftUI 版と一貫しています。

09:02 サイズ設定

ImagePlaygroundOptions で画像サイズを設定できます。

// サイズ指定

var options: ImagePlaygroundOptions {
    var options = ImagePlaygroundOptions()
    options.sizeSpecification = .closest(to: card.format.size)
    return options
}

var body: some View {
    Button("画像を作成") { showingPlayground = true }
        .imagePlaygroundSheet(
            isPresented: $showingPlayground,
            concepts: concepts,
            onCompletion: { url in
                var updated = card
                store.saveImage(url, for: &updated)
            }
        )
        .imagePlaygroundOptions(options)
}

重要な点:

  • .closest(to:)CGSize を受け取ります。
  • システムが最も近いサポート済みアスペクト比と解像度へ自動でマッピングします。
  • 複数フォーマットをサポートする App に適しています。

09:39 スタイル設定

利用可能なスタイルを制限し、プリセットできます。

// スタイル

var options: ImagePlaygroundOptions {
    var options = ImagePlaygroundOptions()
    options.sizeSpecification = .closest(to: card.format.size)
    return options
}

var body: some View {
    Button("画像を作成") { showingPlayground = true }
        .imagePlaygroundSheet(
            isPresented: $showingPlayground,
            concepts: concepts,
            onCompletion: { url in
                var updated = card
                store.saveImage(url, for: &updated)
            }
        )
        .imagePlaygroundOptions(options)
        .imagePlaygroundGenerationStyle(
            pendingStylePreset.defaultStyle,
            in: pendingStylePreset.allowedStyles
        )
}

重要な点:

  • 1つ目の引数はデフォルトで選択されるスタイルです。
  • 2つ目の引数は許可するスタイルの一覧です。
  • 1つのスタイルだけを渡すと、選択 UI はそのスタイルに固定されます。
  • プリセットスタイルには illustrationsketchanimationemoji があります。

10:27 サードパーティスタイル対応

ユーザーが設定で構成したサードパーティ生成サービスにも対応できます。

// 外部プロバイダースタイル

var options: ImagePlaygroundOptions {
    var options = ImagePlaygroundOptions()
    options.sizeSpecification = .closest(to: card.format.size)
    return options
}

var body: some View {
    Button("画像を作成") { showingPlayground = true }
        .imagePlaygroundSheet(
            isPresented: $showingPlayground,
            concepts: concepts,
            onCompletion: { url in
                var updated = card
                store.saveImage(url, for: &updated)
            }
        )
        .imagePlaygroundOptions(options)
        .imagePlaygroundGenerationStyle(
            pendingStylePreset.defaultStyle,
            in: pendingStylePreset.allowedStyles + [.externalProvider]
        )
}

重要な点:

  • .externalProvider は任意で追加できるスタイルです。
  • ユーザーが設定で ChatGPT などを構成すると、このタブが自動的に表示されます。
  • ユーザーが構成済みかどうかを確認する必要はなく、システムが処理します。

11:02 Genmoji アイコン生成

emoji スタイルを使うと、テキストに埋め込めるアダプティブ画像グリフを生成できます。

// カードのサムネイル用に表現力のあるアイコンを生成する

@State private var showingIconPlayground = false

var body: some View {
    Button("アイコンを作成") {
        showingIconPlayground = true
    }
    Color.clear
        .imagePlaygroundSheet(
            isPresented: $showingIconPlayground,
            concepts: concepts,
            onCompletion: { _ in
            } ,
            onAdaptiveImageGlyphCreation: { glyph in
                var updatedCard = card
                store.saveIcon(glyph, for: &updatedCard)
            }
        )
        .imagePlaygroundGenerationStyle(.emoji, in: [.emoji])
}

重要な点:

  • emoji スタイルが有効なとき、onAdaptiveImageGlyphCreation が呼ばれます。
  • コールバックは URL ではなく NSAdaptiveImageGlyph を返します。
  • アダプティブ画像グリフはテキストに直接埋め込め、emoji のように表示できます。

12:01 パーソナライズを無効にする

文脈に合わない場合は、パーソナライズ機能を無効にできます。

// 文脈に合わない場合はパーソナライズを無効にする

var options: ImagePlaygroundOptions {
    var options = ImagePlaygroundOptions()
    options.sizeSpecification = .closest(to: card.format.size)
    options.personalization = .disabled
    return options
}

重要な点:

  • パーソナライズはデフォルトで有効です。
  • 無効にすると、人物ピッカーと名前検出が sheet から消えます。
  • 商品画像生成など、個人化が不要な場面に適しています。

12:32 機能の利用可否を確認する

環境値を使って、デバイスが画像生成をサポートしているか確認します。

// 画像生成をサポートしているか

@Environment(\.supportsImageGeneration)
private var supportsImageGeneration

var body: some View {
    NavigationLink(card.recipient) {
        if supportsImageGeneration {
            CardEditorView(card: card)
        } else {
            CardPickerView(card: card)
        }
    }
}

重要な点:

  • supportsImageGeneration はデバイス性能、言語と地域、ユーザー設定を総合的に考慮します。
  • true の場合だけ完全な体験を表示します。
  • false の場合は、写真ライブラリから選ぶなど別のフローへフォールバックできます。
  • 追加の entitlement や capability チェックは不要です。

重要な示唆

  1. グリーティングカード App のカスタム表紙 — Image Playground は、パーソナライズされたグリーティングカード表紙の生成に自然に適しています。ユーザーが入力したメッセージ、受取人との関係、祝日のテーマを組み合わせて、唯一の画像を生成できます。ユーザーは写真ライブラリから受取人の写真を選び、その人の雰囲気を含むカスタムカードも作れます。

  2. ソーシャルプロフィールのパーソナライズされたアバター — 多くの App はユーザーにアバターやカバー画像のアップロードを許可しています。「AI で生成」オプションを提供し、ニックネーム、自己紹介、興味タグから個性的な画像を生成できます。実際の写真をアップロードしたくないユーザーにとってよい代替になります。

  3. メッセージ App の表現強化 — Messages の実装を参考に、会話内で特定の感情や場面を表す画像を生成できるようにします。たとえば会話内容に基づいて、「お祝い」「励まし」「謝罪」などの画像生成入口を自動提案できます。

  4. コンテンツ制作 App の挿絵生成 — ノート、ブログ、ドキュメント系 App では、「現在の内容に合う挿絵を生成」機能を提供できます。システムがタイトル、キーワード、感情の傾向をコンテキストの種として抽出し、ユーザーは調整するだけで適した挿絵を得られます。

  5. ゲームやソーシャル App のカスタム要素 — ユーザーが個人用アバター、バッジ、フレームなどを生成できるようにします。emoji スタイルでテキストに埋め込めるアダプティブグリフを生成すれば、ユーザー名の横に表示して個性を加えられます。

関連セッション

コメント

GitHub Issues · utterances