- Dart 100%
|
|
||
|---|---|---|
| example | ||
| lib | ||
| reference | ||
| test | ||
| .gitignore | ||
| .gitmodules | ||
| analysis_options.yaml | ||
| CHANGELOG.md | ||
| LICENSE | ||
| pubspec.yaml | ||
| README.md | ||
novelai_image_gen
Strongly-typed Dart bindings for the NovelAI image generation API. Supports text-to-image, img2img, inpainting, vibe transfer, precise character/style reference, and multi-character V4 prompts.
Features
- Text-to-image generation with full control over sampler, steps, guidance, noise schedule
- Img2img and inpainting with automatic image scaling and mask grid alignment
- Vibe transfer using pre-encoded style embeddings
- Precise reference for character likeness and/or artistic style transfer
- Multi-character V4 prompts with per-character tags, gender prefixes, and positioning
- Diffusion 5 (v5) with free-form character positioning and alpha transparency (
v5.dartentrypoint) - Result pattern (
Result<T>) for explicit, type-safe error handling - Tag emphasis via NovelAI's
strength::tag ::format
Getting started
Add the dependency to your pubspec.yaml:
dependencies:
novelai_image_gen: ^1.0.0
You'll need a NovelAI API key. Obtain one from your NovelAI account settings.
Usage
Basic text-to-image
import 'dart:io';
import 'package:novelai_image_gen/novelai_image_gen.dart';
final client = NovelAIClient(
options: NovelAIClientOptions(apiKey: 'your-api-key'),
);
final result = await client.generateImage(
ImageGenerationRequest(
width: 1024,
height: 1024,
positiveTags: [
Tag('1girl'),
Tag('solo'),
Tag.withStrength('detailed background', 1.3),
],
negativeTags: [Tag('lowres'), Tag('bad anatomy')],
),
);
result.match(
onSuccess: (image) => File('output.png').writeAsBytesSync(image.data),
onFailure: (error, statusCode) => print('Failed: $error'),
);
Multi-character scene
final result = await client.generateImage(
ImageGenerationRequest(
width: 1024,
height: 1024,
positiveTags: [Tag('outdoors'), Tag('sunny day')],
characters: [
Character(
gender: CharacterGender.girl,
positiveTags: [Tag('blonde hair'), Tag('blue eyes')],
position: Position.at(0.3, 0.5),
),
Character(
gender: CharacterGender.boy,
positiveTags: [Tag('black hair'), Tag('glasses')],
position: Position.fromGrid(3, 4),
),
],
),
);
Diffusion 5 (V5)
Diffusion 5 models use a separate request tree imported from
package:novelai_image_gen/v5.dart (V5 names collide with V4). Requests
are sent as multipart/form-data; source images and masks are uploaded
raw at native resolution or referenced by server-side cache key:
import 'package:novelai_image_gen/novelai_image_gen.dart';
import 'package:novelai_image_gen/v5.dart' as v5;
final result = await client.generateImage(
v5.ImageGenerationRequest(
width: 1216,
height: 832,
positiveTags: [Tag('1girl'), Tag('street')],
transparentBackground: true,
characters: [
v5.Character(
positiveTags: [Tag('long blonde hair')],
position: v5.Position.at(0.32, 0.48), // free-form, no grid
),
],
),
);
Image-conditioned modes take v5.CachedImage values:
v5.CachedImage.fromData(bytes) uploads, v5.CachedImage.fromCacheKey(key)
reuses a server-side cache entry without uploading. Vibe transfer and
precise reference are not yet available for v5 requests.
Vibe transfer
// 1. Encode a reference image
final vibeResult = await client.encodeVibe(
imageBytes,
Model.diffusion45Full,
informationExtracted: 0.7,
);
// 2. Use the embedding in generation
final genResult = await client.generateImage(
ImageGenerationRequest(
width: 1024,
height: 1024,
positiveTags: [Tag('1girl'), Tag('solo')],
vibeTransfer: VibeTransferOptions(
embedding: vibeResult.valueOrDefault!,
strength: 0.6,
),
),
);
Validate API key
final result = await client.validateApiKey();
print(result.isSuccess ? 'Valid' : 'Invalid: ${result.errorOrDefault}');
See the example for a complete demonstration.
API reference
NovelAIClient
| Method | Returns | Description |
|---|---|---|
generateImage(request) |
Future<Result<GeneratedImage>> |
Generate an image from a prompt |
encodeVibe(imageData, model) |
Future<Result<VibeEmbedding>> |
Encode an image as a vibe embedding |
validateApiKey() |
Future<Result<bool>> |
Check if the API key is valid |
Generation modes
| Mode | Set via | Notes |
|---|---|---|
| Text-to-image | Default | Just provide positiveTags |
| Img2img | img2Img: |
Source image stretched to target size |
| Inpaint | inpaint: |
Requires image + mask; cannot combine with vibe transfer |
| Vibe transfer | vibeTransfer: |
Requires pre-encoded embedding; cannot combine with inpaint |
| Precise reference | preciseReference: |
Style and/or character reference images |
| Multi-character | characters: |
V4 prompt with per-character tags and positioning |
Enums
| Enum | Values |
|---|---|
Model |
diffusion45Full, diffusion45FullInpainting, diffusion5Full, diffusion5FullInpainting |
Sampler |
eulerAncestral, euler, dpmPlusPlus2SAncestral, dpmPlusPlus2M, dpmPlusPlusSde, ddim |
NoiseSchedule |
karras, native_, exponential, polyexponential |
ReferenceType |
style, character, characterAndStyle |
CharacterGender |
none, girl, boy, other |
License
MIT - see LICENSE.