Tutorial: ControlNet preprocessors¶
Use NovelAI’s ControlNet preprocessors to extract a structural map from a
reference image — depth, line art, semantic segmentation. The extracted
annotation is returned as a standalone image you can save or inspect;
generate_image cannot consume it as a ControlNet condition yet.
Workflow overview¶
graph LR
A[Reference image] --> B[annotate_image]
B --> C[Annotation<br/>depth / line art]
C --> D[Save or display]
1. Extract a depth map¶
import base64
from pathlib import Path
photo_b64 = base64.b64encode(Path("photo.png").read_bytes()).decode("ascii")
depth_result = await ctx.session.call_tool("annotate_image", {
"image": photo_b64,
"model": "midas",
})
# depth_result[0] is an Image content block with the depth map;
# depth_result[1] is the saved file path.
2. Try different preprocessors¶
Preprocessor |
Best for |
|---|---|
|
Pose, volumetric composition. |
|
Anime, painterly line preservation. |
|
Loose sketch → coherent line art. |
|
Architecture, interiors, straight lines. |
|
Scene composition, palette transfer. |
for model in ("midas", "hed", "fake_scribble"):
annotation = await ctx.session.call_tool("annotate_image", {
"image": photo_b64,
"model": model,
})
# Save each annotation for inspection
3. CLI equivalent¶
# Extract a depth map
uv run python -m novelai_image_mcp annotate ./photo.png --model midas
4. Current limitations¶
Warning
Generation does not consume annotations yet. generate_image accepts
text prompts, character prompts, and vibe references — but not a
ControlNet condition. There are no controlnet_condition / controlnet_model
parameters on generate_image yet, so an extracted annotation cannot drive a
generation.
Tip
Workaround: For now, combine annotate_image with director_tool to
produce a stylized line-art output from a photo, then optionally use
image_to_image to refine. See Director tools.
What’s next?¶
Vibe transfer — alternate style-transfer workflow