見出し画像

ComfyUI入門:2 ワークフロー構築編

ご挨拶と前置き

こんにちは、インストール編以来ですね!
皆さん、ComfyUIをインストール出来ましたか?

ComfyUI入門1からの続きなので、出来れば入門1から読んできてね!

この記事ではSD1.5のtext to imageのワークフローを構築しながらカスタムノードの追加方法とワークフローに組み込む一連の流れを読みながら一緒に構築するワークショップ形式を取っています。
ComfyUIを初めて触る人の一助となれば幸いです。

  • ComfyUIを触る前にA1111 WebUIで一連の機能、ControlNetに代表される拡張機能群に幅広く触れておいた方がいいです。(確信)

  • この記事ではA1111で代表的な機能には触れた事があるのを前提として書いています。用語や設定項目等もA1111に触れて慣れておいてください。(つまり中級者以上向け)

  • 私自身まだ触れて1週間程度(2024/1/6現在)なので、ガチ勢の方から見ると微妙な内容であることは否めない上に書いてる横から新しい使い方を思いついたりして記事そっちのけで試したいくらいなので、基本に毛が生えた程度の解説しかできません。



用語

殆どはA1111と同じですが、UI周りでちょっとだけ知っておく事があります。
この記事では画像の記述を覚えれば大体OK。
キャンバス、ノード、ワイヤー、接続、データ、ウィジェットこのくらいでOKです。

ComfyUIを起動したところ

キャンバス
ComfyUIの背景のこと、ノード、ワイヤ、メニュー上でないグリッドが見える背景は全てキャンバスと呼びます。

ノード
A1111ではボタンポチーから全自動でやってくれてましたが、ComfyUIでは生成する際に必要となる各工程を「ノード」を繋げ、一連の工程を構築して初めて生成が可能となります。
ノードとは、各工程の機能の一つ一つの事を指します。
ComfyUIではノードを入れ替える事で処理の順序を変更したりループさせたりとA1111では実現できない処理を可能とします。

これがノード。左側の「●model」が入力、右側の「LATENT●」が出力

ワイヤー(リンク)
ノード間をつなぐ線のこと。
現実でもケーブルはそれぞれに必要な情報やエネルギーを伝達するために存在しています。
このワイヤーも同じでノード間で必要とする情報をやり取りするために存在しています。
*公式でも呼び名が不安定なので、この記事内ではワイヤーで表記します。(指摘されるまで気づきませんでした)

接続
ワイヤーを接続した(する)状態
接続と言われたら入出力ウィジェット間でワイヤーを繋ぎましょうということです。

ウィジェット、データ
ノード上で表示されいているものや入力フォーム、ワイヤーを接続する部分等UI上の各部品の総称をウィジェットと呼びます。
各ノードでやりとりする情報や処理を行う情報、値の名称はこの記事内では便宜上データと呼ばせていただきます。(各リファレンスではデータの形式名を記述されている事が殆どです。StepsやCFG等…)
ノードはウィジェットでワイヤーを接続する事でデータの送受信を行います。
*基本的に入力/出力に対応したデータ形式のワイヤーしか接続できません。(ワイヤーの色でも一応判別できます)
*名前の異なる入力/出力から接続できることもあります。(ウィジェットの名前を変更できるため)

*必ずしもノードに設定されている全ての入力/出力を接続しなければならない訳ではありません。
*接続できたからと言って動作が保証されるものではありません。(カスタムノードのReadmeをよく読みましょう。)

ワークフロー
構築した一連の処理のこと
メインメニューのSaveから.json形式にて保存できます。
また、生成した画像にプロンプトやseed値等も含めてワークフローそのものが自動的に埋め込まれます。
そのため、ComfyUIのキャンバス内にComfyUIで生成した画像を放り込むと生成時に利用していたワークフローやデータをそのまま読み込む事ができます。


基本操作

マウス操作

キャンバスをドラッグ/ホイール押し込み = キャンバスの移動
マウスホイール = 拡大縮小

ノードの追加方法

いくつかあります。
これらを知っておくだけで相当楽になるので、必ず触れて使い方を覚えてください。(1敗)

ダブルクリックから検索

右から番号ふってしまいましたわ…

キャンバスをダブルクリックすると、検索ウインドウが出てきます。
①出力の種類から検索
②入力の種類から検索
③ノード名検索
*ウィンドウ外をクリックするかEnterを押すとウインドウは消えます。

右クリックから追加
右クリックメニュー -> Add Node -> 各項目
からノードを追加できます。

カスタムノードに関連するものは同じ項目内に入っていることが多いから、ここから探すのもアリですよ

Add Node
右クリックメニューのものと同じ感覚で使えますよ。

Search
接続先に対応したノードを検索します
入力/出力のドラッグ元が…
出力の場合、入力に対応したノード
入力の場合、出力に対応したノードを
それぞれ自動的に検索してくれます。

未知のノードを使う場合はここから探す方が楽な事もあります。

Searchより下
対応した基本的なノードが表示されます。
欲しいノードが表示されない時は、SearchかAdd Nodeから探しましょう。

あくまで簡易的な機能で、あんまり使う事ないかも。

ノードの操作

ノードそのものも編集できます
データを表示、入力フォームは総称としてウィジェットと言います。

① DnDでノードの移動
② ノードを折り畳んで表示を最小化
③ 右クリック受付エリア
④入力フォーム
プロパティはウィジェットと読み直してね

ノードを右クリック

ModeのAlways=常に有効、Bypass=スルー、他は使った事がないので分かりません。
プロパティパネルはノード名、ノード状態の一括管理パネルを表示します。
Bypassは無効化というより工程をスルーするイメージ。スルーっと。(2024年最大のアツアツでヒエッヒエのミラクルギャグですわ)
ウィジェット上で左クリックするとドロップダウンメニュー又は入力フォームが現れます。
必要な情報を入力しましょう。
値が適切でない場合はエラーが出て有効な範囲や形式が示されます。

グループ

グループは複数のノードを一纏めで管理する機能です。
ノードが増えてくると、いとも簡単に麺ばっかりの特盛ナポリタンスパゲッティが出来てウインナーが食べたいのに見つからないなんてことになっちゃいます。
しかし、グループを使うと特盛スパゲッティの中に隠れたウインナーを探しやすくなります。
(特盛スパゲッティなのは変わりません)

グループ作成
キャンバス上を右クリック -> Add Group

この中に入っているノードは一括して管理することが出来るようになります。
解除したい場合はノードをDnDでグループから出してやるだけです。

こんな感じで構築した人しかわからんような状態なのが…
こんな感じでワイヤーで工程を追うのは大変ですが、グループで管理しておけばグループ間のワイヤーをRerouteノードで管理すれば大まかな流れが見えるようになってスッキリします。
*便利なカスタムノードもありますが、ここでは割愛します。

また、グループを設定すると以下の項目を右クリックから操作できるようになります。
これらの機能はとても便利なので、是非グループを使って区分けするようにしたいところさんです。

Bypass Group Nodes
Save Selected as Template
Node Templates
この3つはとても便利です

基本的なt2iワークフローを構築しよう

まずはおさらい

画像が生成される手順をA1111ではどのようなプロセスで生成していたか、おさらいしましょう。

  1. モデル、プロンプト、VAE、解像度等…必要な情報を入力する

  2. ボタンポチー

  3. イメージ出力

という過程を踏んでましたね。

A1111では意識する事も中々難しいですが、実際は概ね以下のようなプロセスで生成されます。
*SDv1.5のパターンです。

  1. モデル、LoRAの読み込み

    1. VAE内臓の場合、VAEも読み込まれる

  2. CLIPへの情報としてプロンプトやEmbeddingの読み込みと入力

  3. 出力イメージの基本情報入力

    1. 解像度など

  4. サンプラーにモデル、CLIP、基本情報を送信

    1. サンプラー自体にA1111で見慣れた様々な生成に関する設定を入力(step、sampler、Scheduler、seedなど)

  5. サンプラーがノイズから各情報を元に画像生成の工程を実行

  6. VAEデコードで仕上げ

  7. 画像出力

メカニズムや理論はオライリーの本とか読んでください(放棄)

構築してみよう

上記のプロセスに沿ってワークフローを実際に構築していきましょう。

SDv1.5系の基礎的なワークフローはメインメニューの「Load Default」をクリックするとロードされます…が

ここは敢えて「Clear」を押して、基本的なt2iワークフローを一緒に構築していきましょう。(大切)

1 : モデルを読み込むノードとサンプラーを繋げる

キャンバスを右クリック -> Add Node -> loaders

値やモデルを読み込むノードが集中しています。モデル(checkpoint)、VAE、LoRA等
お世話になったSD1.5系のdreamshaperくん、おっすおっす

MODELを入力するKSamplerノードを追加します。

SDXLではKSamplerAdvancedが必要になります

2 : Load CheckpointノードとKSamplerを繋ぐ

なんか見覚えのある単語が書いてあるノードが出て来ましたね。
(Prompt)の名の通り、このノードはプロンプト入力用ノードです。
もちろん、ポジティブ用とネガティブ用両方必要となるので、もう一度操作を行って二つノードを用意します。
この操作から分かる通り、出力からは幾つでもワイヤーを出して各ノードと接続することが可能です。

また、ノード同士が重なって見えにくいので、ノードを見やすい場所に移動させましょう。

CLIP Text Encode(Prompt)をもう一つ用意して移動したところ

同じノードが並んでいて、どちらがポジティブプロンプトのノードか分かりにくいのでノード名を変更しときましょう。
ノード上で右クリック > Properties Panel
画面左にタブが現れましたね。

上から
ノードの上部に表示する文字列
ノードの動作モード
ノードの色
ノードの名前らしい(よくわかってないです)

今回は片方のTitleをPositive Promptにして、もう片方をNegative Promptと名称を変更しておきましょう。

さて、CLIP Text Encodeの出力がCONDITIONINGとなっていますが、KSamplerの入力に同名の入力名がありませんね…
このワイヤーはどこに繋げればいいのでしょうか?

これが記事の最初の方で記述した、別名の出力からでも接続できることがある入力ですが、ご安心を。
出力(入力)をドラッグすると、対応した入力(出力)以外はグレーアウトして、適切な接続先が示されます。

迷ってもこれで安心ですね

同じ要領でネガティブプロンプト側も接続しましょう。

これで、CheckPoint~Samplerへのプロンプトの接続が完了しました。

3 : latent_Imageを繋げる

KSamplerに接続する入力はあと一つですね。
「Latent_image…A1111で聞き覚えはあるけれど、どれかわからへん…」という方でもご安心を。
これまでは、出力から入力を探していましたが、今度は入力側から出力に対応したノードを探してみましょう。

EmptyLatentImageを選択しましょう

4 : KSamplerからVAEデコーダーへ

KSamplerからVAEデコードへ処理を渡します。
VAEDecodeにはVAELoderが必要なので、こちらもノードを接続します。

VAELoderが繋がりましたね
入力されているデータ名が長いと、こんな感じでハミ出たりしますが仕様なので気にしない

5 : VAEからイメージ出力ノードへ繋げる

ようやく画像の出力まで来ました。
これまでと同じ要領でイメージ出力ノードのPreviewImageノードと画像保存ノードのSaveImageノードを接続しましょう。

繋がったよ!

これでワークフローの構築は一旦完了です。
テストしてみましょう。

6 : 設定の入力

これで簡単なワークフローが出来上がりました。
必要な情報を入力してワークフローの動作テストを行いましょう。

好きなモデル、VAE、プロンプトを入力してみましょう。

ウィジェットをクリックして選択
プロンプトを入力、内容は適当にしてみました。

ComfyUIは強調がA1111より強く現れるので、1.4~1.5程度を限度として見ておく方が無難です。

*embeddingsの指定は「embedding:名称 ,」です。
embedding名の後に半角スペースを入力することを守ってください。
embeddingとその周囲のプロンプトを認識しなくなります。
*LoRAを使う場合はLoad LoRAノードを途中で接続する必要があります。
LoRAにトリガーワードを設定している場合はプロンプト内に記入してください。

テストなので512x512で。
batch_sizeは一度のキューで何枚生成するかを意味します。

KSampler、とりあえず無難な設定
VAEはA1111と同じくモデルと相性の良いものを選択してね

KSamplerの設定ですが、無難な設定ということで上記のようにしてみました。
A1111と比較してみましょう。

  • seed = A1111と意味は同じ

  • control_after_generate = seed値を選択した項目に対応したように扱います。

    • fixed(値を固定)

    • increment(生成開始時にseed値から1足した値)

    • decrement(生成開始時にseed値から1引いた値)

    • randomize(ランダムな値)

    • ランダムな値を指定するデータはこのデータもついてきます。覚えておきましょう。

  • steps = A1111と意味は同じ

  • cfg = A1111と意味は同じ

  • sampler_name = A1111ではsampler_name + schedulerで指定していましたが、ComfyUIでは別々に指定することができます。

    • samplerで「_gpu」と付いたものを指定しないとGPUを使わずに生成を始めるので処理が遅くなります。注意。

  • denoise = A1111でアップスケーリングを行う際のdenoising strengthと同じ項目

    • ComfyUIではアップスケーリングをしない時もこの値を調整します。

    • 0.6~0.65を超えてくると怪しくなってきます。

    • A1111とちょっと違い、

7 : 生成テスト

さあ、生成しましょう。
メインメニューのQueue Promptをクリックするか、Ctrl + Enterで生成開始します。

QueuePromptをクリック

数秒待つと…

でたわね

ComfyUIのワークフローはこのように構築していくことになります。
一度出来てしまえば、各データやプロンプトを弄ればいいだけなので、思っているよりも簡単ですよ!

もし、生成してもエラーが出る場合はノードが赤枠で囲まれるので、該当のノードで設定を間違っていたり入力/出力の接続漏れがあったりしますので、確認してみてください。


カスタムノードについて

ここからはカスタムノードを追加して、先ほどのワークフローに組み込んでいきます。

ComfyUIにはA1111で言う拡張機能のカスタムノードがあります。
このチュートリアルでは下記の2種類を使用します。

ComfyUI-Manager
これは必須A1111で言うと、Extentionsタブそのもの。
必ず導入しましょう。
無いとカスタムノードのインストールにgitコマンドをいちいち使うことになって面倒で、すこぶるおファッキューですわ(お下品)操作性が悪いです。

*前記事のComfyUI入門:1 インストール編でインストールが済んでいる事を前提として話を進めます。

ComfyUI-Impact-Pack
これも必須、色んな機能が詰め込まれてます。
高品質アップスケーラーやAfterDetailer辺りもこれに入ってます。
今からこのカスタムノードを追加していきます。

今回はこの二つを利用して基礎的なt2iワークフローを構築していきます。


カスタムノードを追加しよう

ここではカスタムノードを追加し、ワークフローに導入する様子を解説します。
*ここまでに書いた基本的な操作については記入しませんので、分からない箇所はt2iワークフローの項で操作方法を調べてください。

Managerをクリック

リストからインストール

インストール方法は幾つかありますが、今回はInstall Custom Nodesからインストールしてみましょう。
(前記事で載せた雑に意訳した内容も載せておきます)

ComfyUI Managerのメニュー
Install Custom Nodes = リストからインストール

Install Custom Nodesボタンを押すとこのようなリストが現れます。
使い方はA1111の拡張機能リストと同じようなもんです。

めっちゃいっぱいある!こんなにあるなんて知らなかったです…
  • 左上Filter: allはインストール状態に応じて表示を切替

  • 右上のテキストボックスで検索

  • 左下Closeで閉じる

  • 各カスタムノードの右にある「Install」ボタンでインストール

今回はComfyUI Impact Packをインストールしますので、リスト上に無い場合はimpact packで検索してみましょう。(リストの上位にあるならそのままInstallボタン押しちゃってもOK)

インストールが完了すると…

ウインドウの下部がこのようになります

Restartをポチっと

ブラウザの上部にコレが現れます

OKしてComfyUIを再起動しましょう。
今開いているComfyUIタブは閉じちゃいましょう。
(コマンドプロンプトは閉じないでね)

自動的にComfyUIが起動します。
これでComfyUI Managerからカスタムノードの導入は完了です。

リストにないカスタムノードをインストール

Install via Git URLをクリック

URLを入力するだけ!

Detailerをワークフローに追加しよう

今導入したImpactPackノードをワークフローに組み込んでみましょう。
右クリック -> Add Node -> ImpactPack
これがカスタムノードね…ん?

右クリックから…(。´・ω・)ん?
多くない?!

ちょっ…冗談じゃ…

そうなんです、ImpactPackは多機能なカスタムノードで、私もまだ一部の機能しか把握できていません。
しかし、DetailerとUpscaleは導入が手軽でありながら、とても強力でしたので今回紹介することにしました。

FaceDetailerを追加しよう

A1111で言う所のAfterDetailerです。
A1111で大変お世話になった機能ですが、こちらのDetailerも相当優秀です。
今回は簡易的なFaceDetailerを利用して顔と手に適用されるDetailerを追加します。

まず、メインとなるFaceDetailerノードを追加します。
今回は検索から追加してみましょう。

キャンバスをダブルクリックして…

Faceの時点で出て来ましたね
デカい…デカくない?KSamplerよりデカくない?!(ドン引き)

でっ…!でっか!なにこr…ってなりますよね。(私もなりました)
でも、一つずつ見てみると見覚えのあるウィジェットやデータが結構ありますね。

AfterDetailerの代替として使う分には以下の項目を触れればあとはデフォルトでも十分です。

  • Sampler_name、Scheduler

    • KSamplerのやつと同じものを使えばOK

  • denoise、steps、cfg

    • これもKSamplerと同じような扱い方でOK

私もまだ完全に把握していませんがAfterDetailerとして動作する分には満足のできる結果が得られているので今の所触れていません。
(書いている最中に気づきましたが、これそのものをサンプラーとして運用したり、ループさせたりできるようです。検証したら追加の記事を書きます。)

ノードのデカさに圧倒されますが、以下のようにワイヤーを接続していきましょう。
VAE Decode [IMAGE] -> [image]
Load Checkpoint [MODEL] -> [model]
Load Checkpoint [CLIP] -> [clip]
Load VAE [VAE] -> [vae]
*Positive Prompt [CONDITIONING] -> [positive]
*Negative Prompt [CONDITONING] -> [negative]
*CLIPTextEncodeノードのタイトルを変更しましたよね。

美味しそうなスパゲッティが出来てきましたわね♥

未知のノードに接続する必要のある入力/出力はどれかを調べたい時は、生成しちゃうのも一つの手です。
赤枠でエラーの原因箇所が表示されます。

生成が中断され、中断した原因が赤枠で示されます。

原因がわかったので、bbox_detectorに対応したノードを探しましょう。
分からない入力先や出力先に接続したい時は…?そうだね、Searchだね。

どれだろう?

正解は、UltralyticsDetectorProviderでした!

必要なモデルはダウンロードされてます

わかるかー!と思いますが私も迷いました。(公式のreadmeにも載ってませんし、この操作を知らなかったので数時間迷いました)
ここでは顔を対象にするのでface_yolov8m.ptを指定します。

最後に、FaceDetailerのimage出力からPreview imageに接続して完成です。
完成したらQueue Promptかctrl + enterで生成してみましょう。

ワークフローはこうなったよ!

さて、FaceDetailerをワークフローに組み込めたので生成してみましょう

んんん?
修復されてます!

無事修復されているので、FaceDetailerは動作確認できました。
次は手の修復機能を追加してみましょう。
やり方は殆ど変わりません。

HandDetailerを追加しよう

FaceDetailerノードを複製しましょう。
ノードを右クリック -> Clone(ノード複製)

これでノードの複製ができました。

複製したノードの名前はFaceDetailerですが、UltralyticsDetectorProviderノードでhand_yolov8s.ptを指定すれば顔ではなく手を検知するようになります。

FaceDetailerからFaceDetailerへワイヤーを接続しましょう。
さっきやった方法と殆ど変わりませんよ。
FaceDetailer [image] -> [image]
Load Checkpoint [MODEL] -> [model]
Load Checkpoint [CLIP] -> [clip]
Load VAE [VAE] -> [vae]
Positive Prompt [CONDITIONING] -> [positive]
Negative Prompt [CONDITONING] -> [negative]

ちゃっちゃとワイヤーを接続しましょ

UltralyticsDetectorProviderをClone
hand_yolov8.ptに変更
UltralyticsDetectorProvider [BBOX_DETECTOR] -> [bbox_detector]
image -> Preview image [images]
HandDetailerを完成させましょう。

残りも接続して…

二つ目のFaceDetailerは手を対象に動作するので、ノードのタイトルは「HandDetailer」の方が適切ですね。
今のうちに変更しときましょう。

これでワークフローに組み込む作業が完了しました。
さっそく生成してみましょう!

できました!
お見事ですわ!

無事動作していますね!
このように、使うのと使わないのは相当違います。
是非導入してみてくださいね。


Upscalerをワークフローに追加しよう

次はt2i定番の機能アップスケーラーを追加しましょう。

必要となるノードは次の通り

  • ToBasicPipe

  • PixelKSampleUpscalerProviderPipe

  • Iterative Upscale(Latent/on Pixel Space)

この3つです。
ここまでの操作を思い出しながら、ノードを追加しちゃいましょう。

ToBasicPipeを追加
PixelKSampleUpscalerProviderPipeを追加
Iterative Upscale (Latent/on Pixel Space)を追加

ToBasicPipeノードは以下のように接続していきましょう。
Load Checkpoint [MODEL] -> [model]
Load Checkpoint [CLIP] -> [clip]
Load VAE [VAE] -> [vae]
Positive Prompt [CONDITIONING] -> [positive]
Negative Prompt [CONDITONING] -> [negative]

PixelKSampleUpscalerProviderPipeは以下のように接続
ToBasicPipe [basic_pipe] -> [basic_pipe]

Iterative Upscale(Latent/on Pixel Space)は以下のように接続
KSampler [LATENT] ->[samples]
[latent] -> VAE Decode [samples]

スパゲッティが着々とマシマシになってきてますね。
おいしくなーれ♥(憤怒)

接続が完了したら、アップスケーラーの設定をしましょう。

一部試してないのもあるので、試してみてね!(人柱要求)
こんな感じで設定してみました

ワークフローは最終的にはこうなりました。

わ…わわぁ…(ちいかわ)
美味しそうなスパゲッティが出来ましたわね♥

これで基本的なt2iワークフローは完成です!
早速生成してみましょう。

生成例

解像度2倍になっていて、手も顔も良い感じに修正されてますね
ぐぅれいとぉ
手はハズレですね

今回、SD1.5を使ったのは構造がシンプルなため、ComfyUI初心者が触るにはちょうどよいと思ったためです。
(私は最初からSDXLに触れた上に操作方法も分からない状態で凸したので地獄を見ましたチッキショー)

ちなみに、SDXLのRefinerを使わない場合は今回のワークフローでVAEとモデルを用意すればSDXLの利用もできますよ!(akkyossさん、ご指摘ありがとうございました)


まとめ

  • ワークフローに着手する前に一度生成の流れを意識しよう

  • このページを見ながら同じ操作をやってみてノードの探し方を学びましょう

  • 特に注意したい項目

    • プロンプトの強調はA1111より強い

    • embedding:名称 , は厳守(半角スペースに注意!)

    • samplerでは_gpuのものを使おう

    • 入力/出力は全部接続するものではない

    • カスタムノードは必ずreadmeを読んで、サンプルのワークフローを試してから導入しましょう(3敗)


参考にさせて頂いたサイトさま

有志による半公式ComfyUI解説サイト(英語)
ノードの解説などもあります

日本語での解説サイトはこちらがおすすめ
プロンプト仕様の解説で大変お世話になりました

花笠万夜さんのNote
ComfyUIから逃げていた私が使うようになったきっかけ
上のリンクを教えて頂いて大変助かりました
ありがとうございました!


あとがき

いかがでしたか?
ワークフローの構築は出来ましたか?
基本操作とフローの流れが分かれば基礎の生成は出来るものと思います。

しかし、ちょっと処理を割り込ませたりしようとするとフローの流れだけ理解してもちょっと難しくなってきまして、更に一歩踏み込んで各工程では何が起こっているのかを知る必要が出てくるでしょう。

そこで、次回はLatentアップスケーリング、ピクセルアップスケーリング、i2iアップスケーリングのワークフローを構築しながら、もう少し踏み込んで画像生成について知っていきましょう。

それでは次回
「ComfyUI入門:3 アップスケーリングとエンコードについて(仮題)」
でお会いしましょう。
ご機嫌よう。


今後の予定
SDXLのt2iワークフローを構築する
Depth map、normal mapを取得する
PERP-Negを試す
IPAdapterを導入する
ControlNetを導入する

解説してほしいことや要望、感想等があればDMやマシュマロ等で受け付けております。
お気軽にどうぞ!


更新履歴

  • 2024/1/28

    • 一部表現に誤りがあった箇所を修正

    • プロパティ→ウィジェット、入力、出力、データ適切な表現に修正

この記事が気に入ったらサポートをしてみませんか?