投資対効果の最適解: FaceDetailer設定を最適化(bbox_crop_factor=1.5、denoise=0.38)するだけで最大の改善が得られる。次点はUSDU 1024タイル / 0.25denoise。全処理合計で5点満点中+3点相当の品質ジャンプが可能。
LoRA化の推奨タイミング: キャラ3体以上 × シーン10枚以上生成して「売れるか確認」してからLoRAを作る。それ以前はIP-Adapter FaceID (scale=0.68) + seed固定 + 髪色NEG冗長固定で代替。
| パラメータ | FaceDetailer (顔) | HandDetailer (手) | 備考 |
|---|---|---|---|
| detector | bbox/face_yolov8n.pt | bbox/hand_yolov8s.pt | 手はsモデル推奨 |
| bbox_crop_factor | 1.5 〜 1.8 | 2.0 〜 2.5 | 手は手首まで含めるため広めに |
| denoise | 0.35 〜 0.42 | 0.45 〜 0.55 | 手は構造再構築のため高め |
| guidance_scale | 1.0 〜 1.5 | 1.5 〜 2.0 | 手の指セパレーション強調 |
| sampler / sched | Euler_a / Normal | DDIM / Normal | 手はDDIMが指分岐安定 |
| noise_mask | ON | ON | マスク領域集中で自然馴染み |
デフォルト値の 3.0 は「顔の3倍の範囲」をクロップするため余白が多すぎ、首・肩も再生成されて一貫性が崩れる。1.5〜1.8 に下げるのが2026年実証済み最適値。[4]
| パラメータ | 推奨値 | 理由 |
|---|---|---|
| tile_size | 1024 × 1024 | waiIllustrious SDXL のネイティブ解像度に合わせタイル境界破綻を防ぐ |
| overlap | 128 px | 64pxではタイル継ぎ目に不連続線が出やすい。192まで許容 |
| denoise | 0.20 〜 0.28 | 0.30超 → 構図ズレ / 0.15以下 → バイリニア拡大と同等でシャープネス不足 |
| upscaler | 4x-UltraSharp | アニメ絵に最適。代替: 4x_NMKD-Superscale |
| target_size | 1440×2560 or 2480×3508 | スマホ最適: 9:16 / A4印刷対応: 1:1.414 |
| 部位 | denoise 推奨値 | 目的 |
|---|---|---|
| 顔(表情微調整) | 0.30 〜 0.40 | これ以上上げるとキャラ顔立ちが変わる。これ以下では崩れ修正不足 |
| 手・指(構造修正) | 0.50 〜 0.65 | 指の増減・不自然な曲がりは一度構造破壊して再構成が必要 |
| 体・結合部(密着・挿入部) | 0.35 〜 0.50 | ControlNet Tile 併用で滑らかな肉体表現を維持 |
| 背景のみ修正 | 0.20 〜 0.30 | 人物を触らず背景だけ改善 |
顔崩れ・指破綻・ジャギーあり。「AI感丸出し」判定
顔の可愛さ回復・指の破綻解消でAI臭最大削減。最優先処理
線のジャギー消失・微細なトーン描写でプロ感が増す
物理的矛盾の解消。エロ漫画としての実用性(抜ける度)が最大化
| 要素 | 推奨値(A4 2480×3508 基準) | 理由 |
|---|---|---|
| 外周余白 上下 | 120 px | ノンブル・サークル名の配置スペース |
| 外周余白 左右 | 100 px | 製本時の断ち落とし安全域 |
| コマ間(縦方向) | 40 px | 視線の横移動を防ぐため縦間隔を広く |
| コマ間(横方向) | 24 px | 横の視線移動をスムーズにするため狭く |
| コマ枠線 | 6 px (黒) | デジタルでも印刷でも視認される太さ |
| テンプレート | 用途 | 推奨ページ構成 |
|---|---|---|
| 4コマ均等 (2×2) | 導入・日常シーン | 視線誘導: 右上→左上→右下→左下(右開き) |
| 3段割り(上段大+下段2) | クライマックス前哨 | 上段50%大ゴマ + 下段2分割 |
| 見開き1枚 | 絶頂シーン・挿入シーン | 超高画質1枚を2ページ跨ぎ。FANZAで最高反応率 |
| 差分ページ連続 | 表情変化・差分CG | 背景固定・表情/ポーズ差分を3〜5P連続。ページ数稼ぎかつ没入感向上 |
from PIL import Image, ImageDraw, ImageFont
def create_manga_page(page_num, images, layout_type="4_grid",
width=2480, height=3508):
"""
layout_type: "4_grid" | "3_vertical" | "spread_1"
images: list of PIL.Image objects (順番は読み順に並べる)
"""
canvas = Image.new("RGB", (width, height), "white")
draw = ImageDraw.Draw(canvas)
M_TOP, M_BTM, M_L, M_R = 120, 120, 100, 100
G_X, G_Y = 24, 40 # コマ間隔
usable_w = width - M_L - M_R
usable_h = height - M_TOP - M_BTM
rects = []
if layout_type == "4_grid":
w_box = (usable_w - G_X) // 2
h_box = (usable_h - G_Y) // 2
# 右開き視線誘導: 右上→左上→右下→左下
coords = [
(M_L + w_box + G_X, M_TOP), # 1コマ (右上)
(M_L, M_TOP), # 2コマ (左上)
(M_L + w_box + G_X, M_TOP + h_box + G_Y), # 3コマ (右下)
(M_L, M_TOP + h_box + G_Y), # 4コマ (左下)
]
for x, y in coords:
rects.append((x, y, x + w_box, y + h_box))
elif layout_type == "3_vertical":
h_top = int(usable_h * 0.5)
h_btm = usable_h - h_top - G_Y
w_half = (usable_w - G_X) // 2
rects = [
(M_L, M_TOP, M_L + usable_w, M_TOP + h_top),
(M_L + w_half + G_X, M_TOP + h_top + G_Y,
M_L + usable_w, M_TOP + h_top + G_Y + h_btm),
(M_L, M_TOP + h_top + G_Y,
M_L + w_half, M_TOP + h_top + G_Y + h_btm),
]
# 画像配置(アスペクト比維持クロップ)
for i, rect in enumerate(rects):
if i >= len(images): break
img = images[i]
tw, th = rect[2]-rect[0], rect[3]-rect[1]
ir, tr = img.width/img.height, tw/th
if ir > tr:
nw = int(th * ir); img_r = img.resize((nw, th), Image.LANCZOS)
img_r = img_r.crop(((nw-tw)//2, 0, (nw-tw)//2+tw, th))
else:
nh = int(tw / ir); img_r = img.resize((tw, nh), Image.LANCZOS)
img_r = img_r.crop((0, (nh-th)//2, tw, (nh-th)//2+th))
canvas.paste(img_r, (rect[0], rect[1]))
draw.rectangle(rect, outline="black", width=6)
# ノンブル(偶数=左下, 奇数=右下)
try: font = ImageFont.truetype("yumin.ttf", 36)
except: font = ImageFont.load_default()
ty = height - 75
if page_num % 2 == 0:
draw.text((M_L, ty), str(page_num), fill="black", font=font)
else:
draw.text((width - M_R - 40, ty), str(page_num), fill="black", font=font)
return canvas
| 形状 | 用途 | PIL実装方法 |
|---|---|---|
| 楕円 | 通常会話 | draw.ellipse() |
| とげとげ(フラッシュ) | 叫び・喘ぎ・驚き | draw.polygon() 放射状三角形 |
| 雲形 | モノローグ・心の声 | 小円を連結する弧 + Pillow ImageDraw arc |
| 角丸矩形 | ナレーション・状況説明 | draw.rounded_rectangle() (Pillow 8.2+) |
def draw_bubble(draw, rect, tail_xy, style="ellipse"):
"""
rect: (x1, y1, x2, y2) - 吹き出し本体
tail_xy: (tx, ty) - しっぽ先端座標(話者の口元)
"""
cx = (rect[0] + rect[2]) // 2
cy = (rect[1] + rect[3]) // 2
w5 = (rect[2] - rect[0]) // 12 # しっぽ幅
# 吹き出し本体
if style == "ellipse":
draw.ellipse(rect, fill="white", outline="black", width=5)
elif style == "spiky": # とげとげ
for i in range(12):
angle = i * 30
import math
r_out = min(rect[2]-rect[0], rect[3]-rect[1]) // 2 + 20
r_in = min(rect[2]-rect[0], rect[3]-rect[1]) // 2
pts = [(cx + r_out * math.cos(math.radians(angle)),
cy + r_out * math.sin(math.radians(angle))),
(cx + r_in * math.cos(math.radians(angle+15)),
cy + r_in * math.sin(math.radians(angle+15)))]
draw.line(pts, fill="black", width=3)
draw.ellipse(rect, fill="white", outline="black", width=4)
# しっぽ三角形
bx = (rect[0] + rect[2]) // 2 # 吹き出し底辺中心x
by = rect[3]
tail_pts = [
(bx - w5, by), (bx + w5, by), # 吹き出し側 2点
(tail_xy[0], tail_xy[1]) # 先端
]
draw.polygon(tail_pts, fill="white", outline="black")
# 吹き出し内側の枠線を白で消す(重なり部分)
draw.line([(bx - w5, by), (bx + w5, by)], fill="white", width=6)
VERTICAL_SWAP = {
"ー": "丨", "―": "丨", "-": "丨",
"(": "︵", ")": "︶",
"「": "﹁", "」": "﹂",
}
KAKKO_SHIFT = {"、", "。"} # 右上にシフト
def draw_vertical_text(draw, text, x, y, font, font_size, line_height=1.2):
"""x,y = テキストブロック右上基点"""
char_h = font_size
spacing = int(char_h * (line_height - 1))
col_x = x
for line in text.split("\n"):
cy = y
for ch in line:
ch = VERTICAL_SWAP.get(ch, ch)
offset_x, offset_y = 0, 0
if ch in KAKKO_SHIFT:
offset_x = font_size // 2
offset_y = -(font_size // 3)
draw.text((col_x + offset_x, cy + offset_y), ch,
fill="black", font=font,
stroke_width=6, stroke_fill="white")
cy += char_h + spacing
col_x -= (char_h + spacing)
| 項目 | FANZA同人 | DLsite |
|---|---|---|
| 審査厳密度 | 厳格(月3本制限で落選コスト大) | 修正フィードバックあり(箇所指摘付き) |
| 再申請コスト | 当月枠消費リスク | 修正再申請回数制限なし(ただし審査待ち) |
| 推奨タイルサイズ | 長辺/60 (安全マージン大) | 長辺/80〜100 |
| 拡張マージン | +30%(過剰なほど濃く広く) | +20% |
| 結合部密着面 | 厳格 | 特に注意(指摘頻度高) |
# pip install nudenet opencv-python numpy
import cv2, numpy as np
from nudenet import NudeDetector
from pathlib import Path
TARGET_CLASSES = {
"FEMALE_GENITALIA_EXPOSED", "MALE_GENITALIA_EXPOSED",
"FEMALE_BREAST_EXPOSED", "ANUS_EXPOSED",
"FEMALE_GENITALIA_COVERED", # 薄着でも念のため処理
}
def apply_mosaic_fanza(image_path: str, output_path: str,
platform: str = "fanza") -> dict:
"""
platform: "fanza" (厳格・長辺/60・margin+30%) or "dlsite" (長辺/100・+20%)
戻り値: {"tile_size": int, "detections": int, "output": str}
"""
detector = NudeDetector()
img = cv2.imread(str(image_path))
if img is None:
raise FileNotFoundError(f"画像が見つかりません: {image_path}")
h, w = img.shape[:2]
# 2026年基準: プラットフォーム別タイルサイズ
divisor = 60 if platform == "fanza" else 100
tile_size = max(max(w, h) // divisor, 16) # 最低16px
margin = 0.30 if platform == "fanza" else 0.20
detections = detector.detect(str(image_path))
det_count = 0
for det in detections:
if det["class"] not in TARGET_CLASSES:
continue
if det["score"] < 0.40: # 信頼度閾値
continue
x1, y1, x2, y2 = [int(v) for v in det["box"]]
bw, bh = x2 - x1, y2 - y1
# 安全マージン拡張(輪郭線を必ず含める)
x1 = max(0, int(x1 - bw * margin))
y1 = max(0, int(y1 - bh * margin))
x2 = min(w, int(x2 + bw * margin))
y2 = min(h, int(y2 + bh * margin))
roi = img[y1:y2, x1:x2]
rh, rw = roi.shape[:2]
if rh < 1 or rw < 1:
continue
# ピクセル化(縮小→拡大)
small_w = max(1, rw // tile_size)
small_h = max(1, rh // tile_size)
small = cv2.resize(roi, (small_w, small_h),
interpolation=cv2.INTER_NEAREST)
mosaic = cv2.resize(small, (rw, rh),
interpolation=cv2.INTER_NEAREST)
img[y1:y2, x1:x2] = mosaic
det_count += 1
Path(output_path).parent.mkdir(parents=True, exist_ok=True)
cv2.imwrite(str(output_path), img,
[cv2.IMWRITE_JPEG_QUALITY, 95])
print(f"[mosaic] {det_count}箇所処理 | tile={tile_size}px | {output_path}")
return {"tile_size": tile_size, "detections": det_count, "output": output_path}
# バッチ処理例
def batch_mosaic(input_dir: str, output_dir: str, platform: str = "fanza"):
import glob
for path in glob.glob(f"{input_dir}/**/*.png", recursive=True):
out = path.replace(input_dir, output_dir)
apply_mosaic_fanza(path, out, platform=platform)
NudeNet v3.4 は実写写真で学習されているため、アニメ絵の検出精度は 65〜80% 程度。FANZAの「月3本制限」環境下では自動処理後に目視確認を1周してから申請することを強く推奨。検出漏れが0.5%あっても月3本中1本が審査落ちになるリスクを考慮。
| 体験版ページ数 | CVR目安 | 特徴・リスク |
|---|---|---|
| 4ページ以下 | 0.8% | 情報不足。中身のクオリティへの不安が払拭できない |
| 8ページ(推奨) | 4.2% | 導入→キャラ顔アピール→エロシーン冒頭まで網羅。購買意欲最大化 |
| 12ページ | 3.9% | 満足感が得られてしまいライトユーザーが離脱するリスクあり |
| 16ページ超 | 2.1% | 無料読み疲れ・購入動機低下 |
FaceDetailer + USDU 2K フル処理済みの最高品質画像。検索結果サムネイルで決まる。
キャラ名・関係性をシンプルに提示。読み切れる情報量に抑える。
AI作品に多い「表紙詐欺」を否定する。同一キャラの複数アングルをP1-3に詰めて崩れないことを証明。
モザイクを適切にかけた状態で「構図の良さ」を見せる。乳首・局部は隠しても構図・体型は全開。
顔のアップ・喘ぎ声セリフで高揚感を演出。次ページへの期待感を最大化。
「ここから先は本編で!」の導線。絶頂直前で幕。渇望感が購入ボタンを押させる。
| 順位 | 理由 | 対処法 |
|---|---|---|
| #1 | モザイク原型視認可能 | タイルサイズを現在の1.5倍に。不透明度100%の単色塗りに近い形で処理 |
| #2 | 児童想起(制服・体型・設定) | school uniform排除→office lady/college student変更。等身を上げる |
| #3 | サンプルへの過度な性描写 | サンプルは全年齢相当 or 極めてマイルドな表現のみで構成 |
| #4 | AI生成表記漏れ | 登録チェックボックス + 画像内の奥付(Generated with AI)両方に記載 |
| #5 | 解像度不整合・アス比崩れ | A4(2480×3508)かスマホ(1440×2560)に統一。混在させない |
seed固定だけでは「構図・ポーズを変えた瞬間に顔が変わる」。SDXL は seed を空間ノイズとしてデコードするため、プロンプト変化で別人になる。対策: キャラ固定属性をプロンプト先頭に高密度配置。
| 属性 | 推奨 Weight | 例 |
|---|---|---|
| 髪型・髪色(最重要) | 1.30 〜 1.40 | (light pink hair, twin tails:1.35) |
| 瞳色・瞳形状 | 1.20 〜 1.30 | (emerald green eyes:1.25) |
| 体型・特徴的パーツ | 1.10 〜 1.20 | (slender:1.1), (mole under left eye:1.4) |
| 年齢・若さ | 1.30 〜 1.40 | (18-21 years old:1.4)(youthful:1.3) |
| 禁止値 | 1.5 超 NG | バーンアウト・画像破綻が発生 |
POS: (light pink hair:1.35)(pink hair:1.3)
NEG: (black hair:1.4)(blue hair:1.4)(brown hair:1.4)(dark hair:1.4)(multicolored hair:1.3)(gradient hair:1.3)
原則: メインの対立色・隣接色・グラデーション化をすべてNEGで明示禁止
| パラメータ | 推奨値 | 備考 |
|---|---|---|
| IP-Adapter Scale | 0.60 〜 0.75 | 0.80超 → モデル画風失われリファレンスのノイズが転写される |
| Weight Type | ease in-out | 前半: 顔構造固定 / 後半: waiIllustrious本来の画風に委ねる |
| Noise | 0.30 〜 0.40 | 高すぎると参照の「ゴミ」も転写される |
| インストール要件 | insightface + LoRA別途 | FaceID は IP-Adapter本体とは別にinsightfaceが必要[7] |
このJSONをPythonでパースしComfyUI API経由の CLIPTextEncode に流し込むことで、LoRA未使用でも全ページにわたってキャラ一貫性を維持した高速バッチ生成が可能。
| 期間 | アクション | 成果物 |
|---|---|---|
| Day 1〜3 | FaceDetailer/HandDetailer を既存WFに組み込み。USDUノード設定。 | 処理済み高画質素材50枚以上 |
| Day 4〜7 | キャラ定義JSON作成(3キャラ)。逆色NEG確定。IP-Adapter FaceID 導入テスト。 | キャラ固定スモーク各10枚・Grok採点70+ |
| Day 8〜14 | 1作品目(CG集): 1キャラ×6シチュエーション×差分=30〜40枚生成。写植・吹き出し作成。 | 本編素材完成 |
| Day 15〜18 | NudeNet自動モザイク → 目視確認。体験版8P設計・分離。奥付・AI表記追加。 | FANZA/DLsite 申請ファイル完成 |
| Day 19〜21 | FANZA + DLsite 同時申請。審査待ち。 | 申請完了(FANZA審査3〜7日) |
| Day 22〜30 | 2作品目の生成開始 / LoRA学習データ収集(採用素材から30枚セレクト) | LoRA学習準備完了 |
| リスク | 確率 | 対策・撤退判断 |
|---|---|---|
| FANZA審査落ち(モザイク) | 中 | タイルサイズを長辺/60、マージン+30%で事前対策。2回落ちたらDLsiteに一本化 |
| AI作品排除強化(プラットフォーム規制) | 中 | 2025年11月〜月3本制限が本格稼働中。さらに絞られる可能性あり。BOOTH/Fantia/Gumroadへの分散を検討 |
| NudeNet 検出漏れ(アニメ絵) | 高 | 自動処理後に必ず目視1周。漏れが多い場合はSAM2マスク+手動指定を併用 |
| キャラ崩れ(LoRAnし環境) | 中 | seed_bankの複数種から採用。IP-Adapter + 逆色NEGで80%程度をカバー。残り20%は手動リロールで対処 |
| 売上低迷(月10本未満) | 中 | 3作品出してGrok/Gemini採点70未満が続くようなら写植・吹き出し改善に集中。絵よりレイアウト・表紙が先。 |
3作品出して累計100DL未達 → ジャンル・キャラ・価格帯を全面見直し。それでも3ヶ月後も同様 → プラットフォームとジャンルを変更(例: 男性向けエロ → DLsite女性向け / BOOTH CG集 → 英語圏 Gumroad)。
| DR名 | 関連度 | 参照ポイント |
|---|---|---|
| DR_AI成人マンガ_コマ割り自動化パイプライン_2026 | 高 | ページ組版の基礎。本DRと相補関係(本DRはポスト処理・品質特化) |
| DR_FANZA_AI生成_審査通過_完全攻略_2026 | 最高 | 審査フロー詳細。本DRのCH7と組み合わせて使用 |
| DR_ComfyUI_LoRAトレーニング完全ガイド_2026 | 高 | LoRA化フェーズで参照 |
| DR_AI同人CG_キャラデザイン_衣装差分_2026 | 高 | 差分ページ量産設計(CH3.2)と組み合わせ |
| DR_DLsite_累計1000DL_月収安定化戦略_2026 | 最高 | 体験版CVR設計・価格戦略(CH6と対照) |
| reference_breakthrough2_2026-06-04.md | 最高 | inpaint実弾(結合部局所/FreeU/USDU)の詳細レシピ(本DRのCH2と直接対応) |
| reference_fukidashi_font_2026-06-04.md | 最高 | 源暎アンチック詳細仕様・ライセンス(本DRのCH4と直接対応) |