Skip to content

Instantly share code, notes, and snippets.

@rkttu
Last active November 17, 2025 03:57
Show Gist options
  • Select an option

  • Save rkttu/6b6a0fb2bb02fb09ddd4fc23f3a387d1 to your computer and use it in GitHub Desktop.

Select an option

Save rkttu/6b6a0fb2bb02fb09ddd4fc23f3a387d1 to your computer and use it in GitHub Desktop.
A lightweight library for generating AI image prompts

ImagePromptGenerator

A lightweight, fluent C# library for building AI image generation prompts.

This library provides a small set of strongly-typed helper classes and helpers for composing style anchors, negative keywords, and full image generation prompts suitable for use with image generation models or pipelines.

Key features

  • Friendly API for building image prompts using StyleAnchor, StylePrompt, NegativeKeyword, NegativePrompt, and ImageGenerationPrompt.
  • Predefined style anchors covering common categories: sticker, photography, 2D art, 3D rendering, traditional art, and general/abstract.
  • Built-in negative keywords to exclude artifacts and style clashes (e.g., bad hands, watermark, realistic).
  • Preset prompt factories for common use-cases: sticker, 3D icon, photorealistic, and pixel art.
  • Simple string conversion with a default negative postfix --no suitable for many model CLI interfaces.

Quick start

Install or add this project to your solution. The source is minimal and can be referenced directly.

Build and pack the NuGet package (optional):

dotnet pack -o ./nupkgs ImagePromptGenerator.cs
dotnet nuget push ./nupkgs/ImagePromptGenerator.[version].nupkg --api-key $API_KEY --source https://api.nuget.org/v3/index.json

Basic usage

The library uses fluent operators to combine styles and negative keywords.

// Create a style prompt by combining predefined anchors
var style = StyleAnchor.Sticker.Cute
    + StyleAnchor.Sticker.Emoji
    + StyleAnchor.Art2D.CelShaded
    + StyleAnchor.Art2D.VibrantFlatColors;

// Build negative keywords to avoid certain styles and elements
var negative = NegativeKeyword.StyleClash.Photorealistic
    + NegativeKeyword.Elements.Text
    + NegativeKeyword.Elements.Watermark;

// Construct the final prompt
var prompt = new ImageGenerationPrompt(style, "smiling cat with party hat", negative);

// Customize background or subject if needed
prompt.Background = "isolated on a transparent background";

// Convert to string (uses default postfix "--no" for negative prompt)
Console.WriteLine(prompt.ToString());

Output example:

(cute sticker illustration, custom emoji, cel-shaded, vibrant flat colors), smiling cat with party hat, isolated on a transparent background --no (photorealistic, text, watermark)

Preset prompts

The library includes factory methods that return ready-to-use presets:

  • ImageGenerationPrompt.PresetSticker() — optimized for sticker/emoji icons.
  • ImageGenerationPrompt.Preset3DIcon() — for glossy 3D icon renders.
  • ImageGenerationPrompt.PresetPhotorealistic() — for photorealistic images.
  • ImageGenerationPrompt.PresetPixelArt() — for pixel-art / 8-bit style images.

Use them as starting points and then adjust Subject or Background:

var sticker = ImageGenerationPrompt.PresetSticker();
sticker.Subject = "red panda mascot holding a balloon";
Console.WriteLine(sticker);

API Summary

  • StyleAnchor — Defines a single style description; implicitly convertible from string and combines into StylePrompt with +.
  • StylePrompt — A collection of StyleAnchor providing ToString() formatting and convenient operators to combine with anchors, strings, or other prompts.
  • NegativeKeyword — Single negative keyword; implicitly convertible from string and combines into NegativePrompt with +.
  • NegativePrompt — A collection of NegativeKeyword and ToString() implementation to produce a negative list.
  • ImageGenerationPrompt — The final model of the prompt containing Style, Negative, Subject, and Background. It provides a ToString() that uses --no (default) as a negative postfix, and an overloaded ToString(string) to override the postfix.

Combining prompts

Style anchors and negative keywords support + operator for fluent composition. Examples:

var combined = StyleAnchor.Photography.Cinematic + StyleAnchor.Photography.GoldenHour;
var bad = NegativeKeyword.Quality.Blurry + NegativeKeyword.Elements.Text;

These can be passed directly into ImageGenerationPrompt.

Conventions & defaults

  • ImageGenerationPrompt.Background defaults to: isolated on a plain white background.
  • DefaultNegativePromptPostfix defaults to --no — a widely used negative postfix in model CLI style interfaces.

Contributing

Contributions, improvements, new anchors or keywords, and bug reports are welcome. Please fork this repository and open a PR.

License

This project uses the MIT license (see PackageLicenseExpression in project metadata).


If you'd like, I can also add usage examples for specific models (e.g., how to pass these prompts to a Python client or an HTTP API for image generation) — tell me which backend or model you target and I'll add examples.

<Project>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="\"/>
</ItemGroup>
</Project>
#:property OutputType=Library
#:property TargetFramework=net6.0
#:property PublishAot=false
#:property PackageId=ImagePromptGenerator
#:property PackAsTool=false
#:property PackageType=Dependency
#:property Version=0.5.2
#:property Authors=rkttu
#:property Company=rkttu.com
#:property NoDefaultExcludes=true
#:property PackageProjectUrl=https://gist.github.com/rkttu/6b6a0fb2bb02fb09ddd4fc23f3a387d1
#:property RepositoryUrl=https://gist.github.com/rkttu/6b6a0fb2bb02fb09ddd4fc23f3a387d1
#:property PackageReadmeFile=README.md
#:property PackageLicenseExpression=MIT
#:property PackageTags=ai;image-generation;prompt
#:property Description=A lightweight library for generating AI image prompts
#:property RepositoryType=git
// How to build this package:
// dotnet pack -o ./nupkgs ImagePromptGenerator.cs
// dotnet nuget push ./nupkgs/ImagePromptGenerator.[version].nupkg --api-key $API_KEY --source https://api.nuget.org/v3/index.json
namespace ImagePromptGenerator;
using System.Collections.ObjectModel;
/// <summary>
/// Represents a style anchor that defines a specific visual style characteristic for image generation.
/// </summary>
public sealed class StyleAnchor
{
/// <summary>
/// Gets or sets the description of the style anchor.
/// </summary>
/// <summary>
/// Gets or sets the description of the style anchor.
/// </summary>
public string Description { get; set; } = string.Empty;
/// <summary>
/// Explicitly converts a StyleAnchor to a string.
/// </summary>
/// <param name="anchor">The style anchor to convert.</param>
public static explicit operator string(StyleAnchor anchor) => anchor.Description;
/// <summary>
/// Implicitly converts a string to a StyleAnchor.
/// </summary>
/// <param name="description">The description string.</param>
public static implicit operator StyleAnchor(string description) => new StyleAnchor { Description = description, };
/// <summary>
/// Combines two StyleAnchor instances into a StylePrompt.
/// </summary>
/// <param name="left">The left style anchor.</param>
/// <param name="right">The right style anchor.</param>
/// <returns>A new StylePrompt containing both anchors.</returns>
public static StylePrompt operator +(StyleAnchor left, StyleAnchor right) => new StylePrompt { left, right, };
/// <summary>
/// Returns the description of the style anchor.
/// </summary>
/// <returns>The description string.</returns>
public override string ToString() => Description;
/// <summary>
/// Sticker, emoji, and icon styles.
/// </summary>
public static class Sticker
{
/// <summary>
/// Cute sticker illustration style.
/// </summary>
public static readonly StyleAnchor Cute = "cute sticker illustration";
/// <summary>
/// Custom emoji style.
/// </summary>
public static readonly StyleAnchor Emoji = "custom emoji";
/// <summary>
/// Thick bold black outlines style.
/// </summary>
public static readonly StyleAnchor ThickOutlines = "thick bold black outlines";
/// <summary>
/// Playful design style.
/// </summary>
public static readonly StyleAnchor Playful = "playful design";
}
/// <summary>
/// Photography styles.
/// </summary>
public static class Photography
{
/// <summary>
/// Photorealistic style.
/// </summary>
public static readonly StyleAnchor Photorealistic = "photorealistic";
/// <summary>
/// Hyperrealistic style.
/// </summary>
public static readonly StyleAnchor Hyperrealistic = "hyperrealistic";
/// <summary>
/// Cinematic style.
/// </summary>
public static readonly StyleAnchor Cinematic = "cinematic";
/// <summary>
/// Cinematic lighting style.
/// </summary>
public static readonly StyleAnchor CinematicLighting = "cinematic lighting";
/// <summary>
/// Studio lighting style.
/// </summary>
public static readonly StyleAnchor StudioLighting = "studio lighting";
/// <summary>
/// Golden hour lighting style.
/// </summary>
public static readonly StyleAnchor GoldenHour = "golden hour";
/// <summary>
/// DSLR photo style.
/// </summary>
public static readonly StyleAnchor DSLR = "DSLR photo";
/// <summary>
/// Film grain effect.
/// </summary>
public static readonly StyleAnchor FilmGrain = "film grain";
/// <summary>
/// Analog film style.
/// </summary>
public static readonly StyleAnchor AnalogFilm = "analog film";
/// <summary>
/// Bokeh effect.
/// </summary>
public static readonly StyleAnchor Bokeh = "bokeh";
/// <summary>
/// Long exposure effect.
/// </summary>
public static readonly StyleAnchor LongExposure = "long exposure";
/// <summary>
/// High resolution style.
/// </summary>
public static readonly StyleAnchor HighResolution = "high resolution";
/// <summary>
/// Ultra detailed style.
/// </summary>
public static readonly StyleAnchor UltraDetailed = "ultra detailed";
/// <summary>
/// Sharp focus style.
/// </summary>
public static readonly StyleAnchor SharpFocus = "sharp focus";
}
/// <summary>
/// 2D art and illustration styles.
/// </summary>
public static class Art2D
{
/// <summary>
/// Digital art style.
/// </summary>
public static readonly StyleAnchor DigitalArt = "digital art";
/// <summary>
/// Concept art style.
/// </summary>
public static readonly StyleAnchor ConceptArt = "concept art";
/// <summary>
/// Vector illustration style.
/// </summary>
public static readonly StyleAnchor Vector = "vector illustration";
/// <summary>
/// Flat design style.
/// </summary>
public static readonly StyleAnchor FlatDesign = "flat design";
/// <summary>
/// Cel-shaded style.
/// </summary>
public static readonly StyleAnchor CelShaded = "cel-shaded";
/// <summary>
/// Vibrant flat colors style.
/// </summary>
public static readonly StyleAnchor VibrantFlatColors = "vibrant flat colors";
/// <summary>
/// Clean linework style.
/// </summary>
public static readonly StyleAnchor Linework = "clean linework";
/// <summary>
/// Anime style.
/// </summary>
public static readonly StyleAnchor Anime = "anime style";
/// <summary>
/// Studio Ghibli style.
/// </summary>
public static readonly StyleAnchor Ghibli = "Ghibli style";
/// <summary>
/// Pixel art style.
/// </summary>
public static readonly StyleAnchor PixelArt = "pixel art";
/// <summary>
/// 8-bit style.
/// </summary>
public static readonly StyleAnchor _8bit = "8-bit";
/// <summary>
/// Limited color palette style.
/// </summary>
public static readonly StyleAnchor LimitedColorPalette = "limited color palette";
}
/// <summary>
/// 3D rendering styles.
/// </summary>
public static class Render3D
{
/// <summary>
/// 3D render style.
/// </summary>
public static readonly StyleAnchor Render = "3D render";
/// <summary>
/// Octane render style.
/// </summary>
public static readonly StyleAnchor Octane = "Octane render";
/// <summary>
/// Unreal Engine style.
/// </summary>
public static readonly StyleAnchor Unreal = "Unreal Engine";
/// <summary>
/// Low-poly style.
/// </summary>
public static readonly StyleAnchor LowPoly = "low-poly";
/// <summary>
/// Glossy plastic finish style.
/// </summary>
public static readonly StyleAnchor GlossyPlastic = "glossy plastic finish";
/// <summary>
/// Smooth shading style.
/// </summary>
public static readonly StyleAnchor SmoothShading = "smooth shading";
}
/// <summary>
/// Traditional art styles.
/// </summary>
public static class TraditionalArt
{
/// <summary>
/// Oil painting style.
/// </summary>
public static readonly StyleAnchor OilPainting = "oil painting";
/// <summary>
/// Watercolor painting style.
/// </summary>
public static readonly StyleAnchor Watercolor = "watercolor painting";
/// <summary>
/// Sketch style.
/// </summary>
public static readonly StyleAnchor Sketch = "sketch";
/// <summary>
/// Charcoal drawing style.
/// </summary>
public static readonly StyleAnchor Charcoal = "charcoal drawing";
/// <summary>
/// Impasto (thick paint) style.
/// </summary>
public static readonly StyleAnchor Impasto = "impasto (thick paint)";
/// <summary>
/// Ink drawing style.
/// </summary>
public static readonly StyleAnchor InkDrawing = "ink drawing";
}
/// <summary>
/// General and abstract styles.
/// </summary>
public static class General
{
/// <summary>
/// Minimalist style.
/// </summary>
public static readonly StyleAnchor Minimalist = "minimalist";
/// <summary>
/// Abstract style.
/// </summary>
public static readonly StyleAnchor Abstract = "abstract";
/// <summary>
/// Surreal style.
/// </summary>
public static readonly StyleAnchor Surreal = "surreal";
/// <summary>
/// Fantasy style.
/// </summary>
public static readonly StyleAnchor Fantasy = "fantasy";
/// <summary>
/// Science fiction style.
/// </summary>
public static readonly StyleAnchor SciFi = "sci-fi";
/// <summary>
/// Cyberpunk style.
/// </summary>
public static readonly StyleAnchor Cyberpunk = "cyberpunk";
}
}
/// <summary>
/// Represents a collection of style anchors that form a complete style prompt.
/// </summary>
public sealed class StylePrompt : Collection<StyleAnchor>
{
/// <summary>
/// Initializes a new instance of the <see cref="StylePrompt"/> class.
/// </summary>
public StylePrompt() : base() { }
/// <summary>
/// Initializes a new instance of the <see cref="StylePrompt"/> class with the specified anchors.
/// </summary>
/// <param name="anchors">The style anchors to include.</param>
public StylePrompt(params StyleAnchor[] anchors) : base(anchors) { }
/// <summary>
/// Initializes a new instance of the <see cref="StylePrompt"/> class with the specified collection.
/// </summary>
/// <param name="enumerable">The collection of style anchors.</param>
/// <summary>
/// Initializes a new instance of the <see cref="StylePrompt"/> class with the specified collection.
/// </summary>
/// <param name="enumerable">The collection of style anchors.</param>
public StylePrompt(IEnumerable<StyleAnchor> enumerable) : base(enumerable.ToList()) { }
/// <summary>
/// Implicitly converts a StylePrompt to an array of StyleAnchor.
/// </summary>
/// <param name="prompt">The style prompt to convert.</param>
public static implicit operator StyleAnchor[](StylePrompt prompt) => prompt.ToArray();
/// <summary>
/// Implicitly converts an array of StyleAnchor to a StylePrompt.
/// </summary>
/// <param name="anchors">The array of style anchors.</param>
public static implicit operator StylePrompt(StyleAnchor[] anchors) => new StylePrompt(anchors);
/// <summary>
/// Combines a StylePrompt with a string to create a new StylePrompt.
/// </summary>
/// <param name="left">The style prompt.</param>
/// <param name="right">The string to add.</param>
/// <returns>A new StylePrompt with the combined elements.</returns>
public static StylePrompt operator +(StylePrompt left, string right) => new StylePrompt(Enumerable.Concat(left, new StyleAnchor[] { (StyleAnchor)right, }));
/// <summary>
/// Combines a StylePrompt with a StyleAnchor to create a new StylePrompt.
/// </summary>
/// <param name="left">The style prompt.</param>
/// <param name="right">The style anchor to add.</param>
/// <returns>A new StylePrompt with the combined elements.</returns>
public static StylePrompt operator +(StylePrompt left, StyleAnchor right) => new StylePrompt(Enumerable.Concat(left, new StyleAnchor[] { right, }));
/// <summary>
/// Combines two StylePrompt instances to create a new StylePrompt.
/// </summary>
/// <param name="left">The first style prompt.</param>
/// <param name="right">The second style prompt.</param>
/// <returns>A new StylePrompt with the combined elements.</returns>
public static StylePrompt operator +(StylePrompt left, StylePrompt right) => new StylePrompt(Enumerable.Concat(left, right.ToArray()));
/// <summary>
/// Combines a StylePrompt with a collection of strings to create a new StylePrompt.
/// </summary>
/// <param name="left">The style prompt.</param>
/// <param name="right">The collection of strings to add.</param>
/// <returns>A new StylePrompt with the combined elements.</returns>
public static StylePrompt operator +(StylePrompt left, IEnumerable<string> right) => new StylePrompt(Enumerable.Concat(left, right.Select(x => (StyleAnchor)x).ToArray()));
/// <summary>
/// Combines a StylePrompt with a collection of StyleAnchor to create a new StylePrompt.
/// </summary>
/// <param name="left">The style prompt.</param>
/// <param name="right">The collection of style anchors to add.</param>
/// <returns>A new StylePrompt with the combined elements.</returns>
public static StylePrompt operator +(StylePrompt left, IEnumerable<StyleAnchor> right) => new StylePrompt(Enumerable.Concat(left, right.ToArray()));
/// <summary>
/// Returns a string representation of the style prompt.
/// </summary>
/// <returns>A formatted string containing all style descriptions.</returns>
public override string ToString() => "(" + string.Join(", ", this.Select(x => x.Description)) + ")";
/// <summary>
/// Gets an empty StylePrompt instance.
/// </summary>
public static readonly StylePrompt Empty = new StylePrompt();
}
/// <summary>
/// Represents a negative keyword to exclude from image generation.
/// </summary>
public sealed class NegativeKeyword
{
/// <summary>
/// Gets or sets the description of the negative keyword.
/// </summary>
/// <summary>
/// Gets or sets the description of the negative keyword.
/// </summary>
public string Description { get; set; } = string.Empty;
/// <summary>
/// Explicitly converts a NegativeKeyword to a string.
/// </summary>
/// <param name="keyword">The negative keyword to convert.</param>
public static explicit operator string(NegativeKeyword keyword) => keyword.Description;
/// <summary>
/// Implicitly converts a string to a NegativeKeyword.
/// </summary>
/// <param name="description">The description string.</param>
public static implicit operator NegativeKeyword(string description) => new NegativeKeyword { Description = description, };
/// <summary>
/// Combines two NegativeKeyword instances into a NegativePrompt.
/// </summary>
/// <param name="left">The left negative keyword.</param>
/// <param name="right">The right negative keyword.</param>
/// <returns>A new NegativePrompt containing both keywords.</returns>
public static NegativePrompt operator +(NegativeKeyword left, NegativeKeyword right) => new NegativePrompt { left, right, };
/// <summary>
/// Returns the description of the negative keyword.
/// </summary>
/// <returns>The description string.</returns>
public override string ToString() => Description;
/// <summary>
/// Image quality degradation elements.
/// </summary>
public static class Quality
{
/// <summary>
/// Low quality.
/// </summary>
public static readonly NegativeKeyword Low = "low quality";
/// <summary>
/// Worst quality.
/// </summary>
public static readonly NegativeKeyword Worst = "worst quality";
/// <summary>
/// JPEG artifacts.
/// </summary>
public static readonly NegativeKeyword JpegArtifacts = "jpeg artifacts";
/// <summary>
/// Blurry image.
/// </summary>
public static readonly NegativeKeyword Blurry = "blurry";
/// <summary>
/// Image noise.
/// </summary>
public static readonly NegativeKeyword Noise = "noise";
}
/// <summary>
/// Anatomical and morphological errors.
/// </summary>
public static class Anatomy
{
/// <summary>
/// Deformed appearance.
/// </summary>
public static readonly NegativeKeyword Deformed = "deformed";
/// <summary>
/// Bad anatomy.
/// </summary>
public static readonly NegativeKeyword BadAnatomy = "bad anatomy";
/// <summary>
/// Malformed hands.
/// </summary>
public static readonly NegativeKeyword BadHands = "malformed hands";
/// <summary>
/// Extra fingers.
/// </summary>
public static readonly NegativeKeyword ExtraFingers = "extra fingers";
/// <summary>
/// Too many fingers.
/// </summary>
public static readonly NegativeKeyword TooManyFingers = "too many fingers";
/// <summary>
/// Extra limbs.
/// </summary>
public static readonly NegativeKeyword ExtraLimbs = "extra limbs";
/// <summary>
/// Disfigured appearance.
/// </summary>
public static readonly NegativeKeyword Disfigured = "disfigured";
/// <summary>
/// Ugly appearance.
/// </summary>
public static readonly NegativeKeyword Ugly = "ugly";
}
/// <summary>
/// Unwanted subjects and elements.
/// </summary>
public static class Elements
{
/// <summary>
/// Text in the image.
/// </summary>
public static readonly NegativeKeyword Text = "text";
/// <summary>
/// Words in the image.
/// </summary>
public static readonly NegativeKeyword Words = "words";
/// <summary>
/// Letters in the image.
/// </summary>
public static readonly NegativeKeyword Letters = "letters";
/// <summary>
/// Signature in the image.
/// </summary>
public static readonly NegativeKeyword Signature = "signature";
/// <summary>
/// Watermark in the image.
/// </summary>
public static readonly NegativeKeyword Watermark = "watermark";
/// <summary>
/// Username in the image.
/// </summary>
public static readonly NegativeKeyword Username = "username";
/// <summary>
/// Cropped image.
/// </summary>
public static readonly NegativeKeyword Cropped = "cropped";
/// <summary>
/// Elements out of frame.
/// </summary>
public static readonly NegativeKeyword OutOfFrame = "out of frame";
/// <summary>
/// Shadow in the image.
/// </summary>
public static readonly NegativeKeyword Shadow = "shadow";
}
/// <summary>
/// Style clash prevention keywords.
/// </summary>
public static class StyleClash
{
/// <summary>
/// Realistic style to avoid.
/// </summary>
public static readonly NegativeKeyword Realistic = "realistic";
/// <summary>
/// Photorealistic style to avoid.
/// </summary>
public static readonly NegativeKeyword Photorealistic = "photorealistic";
/// <summary>
/// Soft shading to avoid.
/// </summary>
public static readonly NegativeKeyword SoftShading = "soft shading";
/// <summary>
/// Gradient effect to avoid.
/// </summary>
public static readonly NegativeKeyword Gradient = "gradient";
/// <summary>
/// Painting style to avoid.
/// </summary>
public static readonly NegativeKeyword Painting = "painting";
/// <summary>
/// Drawing style to avoid.
/// </summary>
public static readonly NegativeKeyword Drawing = "drawing";
/// <summary>
/// Sketch style to avoid.
/// </summary>
public static readonly NegativeKeyword Sketch = "sketch";
/// <summary>
/// 3D style to avoid.
/// </summary>
public static readonly NegativeKeyword _3D = "3D";
/// <summary>
/// Render style to avoid.
/// </summary>
public static readonly NegativeKeyword Render = "render";
/// <summary>
/// Anime style to avoid.
/// </summary>
public static readonly NegativeKeyword Anime = "anime";
/// <summary>
/// Complex background to avoid.
/// </summary>
public static readonly NegativeKeyword ComplexBackground = "complex background";
/// <summary>
/// Anti-aliasing effect to avoid.
/// </summary>
public static readonly NegativeKeyword AntiAliasing = "anti-aliasing";
}
}
/// <summary>
/// Represents a collection of negative keywords to exclude from image generation.
/// </summary>
public sealed class NegativePrompt : Collection<NegativeKeyword>
{
/// <summary>
/// Initializes a new instance of the <see cref="NegativePrompt"/> class.
/// </summary>
public NegativePrompt() : base() { }
/// <summary>
/// Initializes a new instance of the <see cref="NegativePrompt"/> class with the specified keywords.
/// </summary>
/// <param name="anchors">The negative keywords to include.</param>
public NegativePrompt(params NegativeKeyword[] anchors) : base(anchors) { }
/// <summary>
/// Initializes a new instance of the <see cref="NegativePrompt"/> class with the specified collection.
/// </summary>
/// <param name="enumerable">The collection of negative keywords.</param>
/// <summary>
/// Initializes a new instance of the <see cref="NegativePrompt"/> class with the specified collection.
/// </summary>
/// <param name="enumerable">The collection of negative keywords.</param>
public NegativePrompt(IEnumerable<NegativeKeyword> enumerable) : base(enumerable.ToList()) { }
/// <summary>
/// Combines a NegativePrompt with a string to create a new NegativePrompt.
/// </summary>
/// <param name="left">The negative prompt.</param>
/// <param name="right">The string to add.</param>
/// <returns>A new NegativePrompt with the combined elements.</returns>
public static NegativePrompt operator +(NegativePrompt left, string right) => new NegativePrompt(Enumerable.Concat(left, new NegativeKeyword[] { (NegativeKeyword)right, }));
/// <summary>
/// Combines a NegativePrompt with a NegativeKeyword to create a new NegativePrompt.
/// </summary>
/// <param name="left">The negative prompt.</param>
/// <param name="right">The negative keyword to add.</param>
/// <returns>A new NegativePrompt with the combined elements.</returns>
public static NegativePrompt operator +(NegativePrompt left, NegativeKeyword right) => new NegativePrompt(Enumerable.Concat(left, new NegativeKeyword[] { right, }));
/// <summary>
/// Combines two NegativePrompt instances to create a new NegativePrompt.
/// </summary>
/// <param name="left">The first negative prompt.</param>
/// <param name="right">The second negative prompt.</param>
/// <returns>A new NegativePrompt with the combined elements.</returns>
public static NegativePrompt operator +(NegativePrompt left, NegativePrompt right) => new NegativePrompt(Enumerable.Concat(left, right.ToArray()));
/// <summary>
/// Combines a NegativePrompt with a collection of strings to create a new NegativePrompt.
/// </summary>
/// <param name="left">The negative prompt.</param>
/// <param name="right">The collection of strings to add.</param>
/// <returns>A new NegativePrompt with the combined elements.</returns>
public static NegativePrompt operator +(NegativePrompt left, IEnumerable<string> right) => new NegativePrompt(Enumerable.Concat(left, right.Select(x => (NegativeKeyword)x).ToArray()));
/// <summary>
/// Combines a NegativePrompt with a collection of NegativeKeyword to create a new NegativePrompt.
/// </summary>
/// <param name="left">The negative prompt.</param>
/// <param name="right">The collection of negative keywords to add.</param>
/// <returns>A new NegativePrompt with the combined elements.</returns>
public static NegativePrompt operator +(NegativePrompt left, IEnumerable<NegativeKeyword> right) => new NegativePrompt(Enumerable.Concat(left, right.ToArray()));
/// <summary>
/// Returns a string representation of the negative prompt.
/// </summary>
/// <returns>A formatted string containing all negative keyword descriptions.</returns>
public override string ToString() => "(" + string.Join(", ", this.Select(x => x.Description)) + ")";
/// <summary>
/// Gets an empty NegativePrompt instance.
/// </summary>
public static readonly NegativePrompt Empty = new NegativePrompt();
}
/// <summary>
/// Represents a complete image generation prompt including style, subject, background, and negative keywords.
/// </summary>
public sealed class ImageGenerationPrompt
{
/// <summary>
/// Gets the style prompt for the image.
/// </summary>
public StylePrompt Style { get; }
/// <summary>
/// Gets the negative prompt for the image.
/// </summary>
public NegativePrompt Negative { get; }
/// <summary>
/// Gets or sets the subject of the image.
/// </summary>
public string Subject { get; set; } = string.Empty;
/// <summary>
/// Gets or sets the background description of the image. Default is "isolated on a plain white background".
/// </summary>
public string Background { get; set; } = "isolated on a plain white background";
/// <summary>
/// Gets the default negative prompt postfix. Default is "--no".
/// </summary>
public static readonly string DefaultNegativePromptPostfix = "--no";
/// <summary>
/// Initializes a new instance of the <see cref="ImageGenerationPrompt"/> class with the specified style and negative prompts.
/// </summary>
/// <param name="style">The style prompt.</param>
/// <param name="negative">The negative prompt.</param>
/// <summary>
/// Initializes a new instance of the <see cref="ImageGenerationPrompt"/> class with the specified style and negative prompts.
/// </summary>
/// <param name="style">The style prompt.</param>
/// <param name="negative">The negative prompt.</param>
public ImageGenerationPrompt(StylePrompt style, NegativePrompt negative)
{
Style = style;
Negative = negative;
}
/// <summary>
/// Initializes a new instance of the <see cref="ImageGenerationPrompt"/> class with the specified style, subject, and negative prompts.
/// </summary>
/// <param name="style">The style prompt.</param>
/// <param name="subject">The subject of the image.</param>
/// <param name="negative">The negative prompt.</param>
public ImageGenerationPrompt(StylePrompt style, string subject, NegativePrompt negative)
: this(style, negative)
{
Subject = subject;
}
/// <summary>
/// Converts the image generation prompt to a string with a custom negative prompt postfix.
/// </summary>
/// <param name="negativePromptPostfix">The postfix to use for negative prompts.</param>
/// <returns>A formatted prompt string.</returns>
/// <summary>
/// Converts the image generation prompt to a string with a custom negative prompt postfix.
/// </summary>
/// <param name="negativePromptPostfix">The postfix to use for negative prompts.</param>
/// <returns>A formatted prompt string.</returns>
public string ToString(string negativePromptPostfix)
{
var stylePart = Style.Any() ? Style.ToString() : string.Empty;
var subjectPart = Subject;
var backgroundPart = Background;
var negativePart = Negative.Any() ? $"{negativePromptPostfix} {Negative.ToString()}" : string.Empty;
var parts = new[] { stylePart, subjectPart, backgroundPart }.Where(s => !string.IsNullOrEmpty(s));
return string.Join(", ", parts) + " " + negativePart;
}
/// <summary>
/// Returns a string representation of the image generation prompt using the default negative prompt postfix.
/// </summary>
/// <returns>A formatted prompt string.</returns>
public override string ToString() => ToString(DefaultNegativePromptPostfix);
/// <summary>
/// Creates a preset prompt for sticker-style image generation.
/// </summary>
/// <returns>An ImageGenerationPrompt configured for sticker style.</returns>
public static ImageGenerationPrompt PresetSticker()
{
var style = StyleAnchor.Sticker.Cute
+ StyleAnchor.Sticker.Emoji
+ StyleAnchor.Sticker.ThickOutlines
+ StyleAnchor.Art2D.CelShaded
+ StyleAnchor.Art2D.VibrantFlatColors;
var negative = NegativeKeyword.StyleClash.Realistic
+ NegativeKeyword.StyleClash.Photorealistic
+ NegativeKeyword.StyleClash.SoftShading
+ NegativeKeyword.StyleClash.Gradient
+ NegativeKeyword.Elements.Shadow
+ NegativeKeyword.Elements.Text;
return new ImageGenerationPrompt(style, negative);
}
/// <summary>
/// Creates a preset prompt for 3D icon-style image generation.
/// </summary>
/// <returns>An ImageGenerationPrompt configured for 3D icon style.</returns>
public static ImageGenerationPrompt Preset3DIcon()
{
var style = StyleAnchor.Render3D.Render
+ StyleAnchor.Render3D.Octane
+ StyleAnchor.Render3D.GlossyPlastic
+ StyleAnchor.Render3D.SmoothShading
+ StyleAnchor.General.Minimalist;
var negative = NegativeKeyword.StyleClash.Realistic
+ NegativeKeyword.StyleClash.Photorealistic
+ NegativeKeyword.StyleClash.Sketch
+ NegativeKeyword.Elements.Text
+ NegativeKeyword.Quality.Noise;
return new ImageGenerationPrompt(style, negative);
}
/// <summary>
/// Creates a preset prompt for photorealistic image generation.
/// </summary>
/// <returns>An ImageGenerationPrompt configured for photorealistic style.</returns>
public static ImageGenerationPrompt PresetPhotorealistic()
{
var style = StyleAnchor.Photography.Photorealistic
+ StyleAnchor.Photography.Hyperrealistic
+ StyleAnchor.Photography.DSLR
+ StyleAnchor.Photography.CinematicLighting
+ StyleAnchor.Photography.HighResolution
+ StyleAnchor.Photography.SharpFocus;
var negative = NegativeKeyword.StyleClash.Painting
+ NegativeKeyword.StyleClash.Drawing
+ NegativeKeyword.StyleClash.Sketch
+ NegativeKeyword.StyleClash.Anime
+ NegativeKeyword.StyleClash._3D
+ NegativeKeyword.StyleClash.Render
+ NegativeKeyword.Quality.Blurry
+ NegativeKeyword.Elements.Text
+ NegativeKeyword.Elements.Watermark;
return new ImageGenerationPrompt(style, negative);
}
/// <summary>
/// Creates a preset prompt for pixel art-style image generation.
/// </summary>
/// <returns>An ImageGenerationPrompt configured for pixel art style.</returns>
public static ImageGenerationPrompt PresetPixelArt()
{
var style = StyleAnchor.Art2D.PixelArt
+ StyleAnchor.Art2D._8bit
+ StyleAnchor.Art2D.LimitedColorPalette;
var negative = NegativeKeyword.StyleClash.Photorealistic
+ NegativeKeyword.StyleClash.SoftShading
+ NegativeKeyword.StyleClash.Gradient
+ NegativeKeyword.Quality.Blurry
+ NegativeKeyword.StyleClash.AntiAliasing;
return new ImageGenerationPrompt(style, negative);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment