Meziantou.Framework.Avatar 2.1.9

Prefix Reserved
dotnet add package Meziantou.Framework.Avatar --version 2.1.9
                    
NuGet\Install-Package Meziantou.Framework.Avatar -Version 2.1.9
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Meziantou.Framework.Avatar" Version="2.1.9" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Meziantou.Framework.Avatar" Version="2.1.9" />
                    
Directory.Packages.props
<PackageReference Include="Meziantou.Framework.Avatar" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Meziantou.Framework.Avatar --version 2.1.9
                    
#r "nuget: Meziantou.Framework.Avatar, 2.1.9"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Meziantou.Framework.Avatar@2.1.9
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Meziantou.Framework.Avatar&version=2.1.9
                    
Install as a Cake Addin
#tool nuget:?package=Meziantou.Framework.Avatar&version=2.1.9
                    
Install as a Cake Tool

Meziantou.Framework.Avatar

Generate deterministic avatars from a name, as SVG strings or as vector scenes to draw as PNG images.

Usage

The types are in the Meziantou.Framework namespace.

var svg = AvatarGenerator.CreateSvg("John Doe");
Assert.StartsWith("<svg ", svg);
Assert.Contains("aria-label=\"JD\"", svg);

AvatarGenerator extracts a 1-2 grapheme bigram from the name and selects a background/foreground pair from the palette using a hash of the name.

Customize the output

var options = new AvatarOptions
{
    Bigram = "JD", // optional explicit 1-2 grapheme bigram
    Shape = AvatarShape.Round, // Round, Square, or RoundedSquare
    Size = 128,
};
options.Palette.Clear();
options.Palette.Add(new AvatarColorPair("#CFDADE", "#153037")); // background, then foreground

var svg = AvatarGenerator.CreateSvg("John Doe", options);
Assert.Contains("width=\"128\" height=\"128\"", svg);
Assert.Contains("<circle cx=\"64\" cy=\"64\" r=\"64\" fill=\"#CFDADE\"/>", svg);

Render as PNG

AvatarGenerator.CreateScene returns the avatar as a Scene of Meziantou.Framework.VectorGraphics. Meziantou.Framework.Imaging.VectorGraphics draws it as an image:

// Lay the avatar out with the fonts that draw the image, so the initials are centered
var measurer = SceneImageRenderer.CreateMeasurer();
var scene = AvatarGenerator.CreateScene("John Doe", new AvatarOptions { Size = 128 }, measurer);

using var image = scene.ToImage();
Assert.Equal((128, 128), (image.Width, image.Height));

// Save to a file (image.Save("avatar.png")) or to a stream, in any format
using var png = new MemoryStream();
image.Save(png, new PngEncoder());

The initials are centered with the metrics of the measurer, so lay the scene out with the measurer of the fonts that draw it. The embedded fonts only cover the Latin characters: for other scripts, pass a SceneFontCollection with fallback fonts in SceneImageOptions.Fonts to CreateMeasurer. The scene keeps the fonts of the measurer (Scene.Fonts), so ToImage draws the initials with them, and SvgRenderOptions.EmbedFonts embeds them in its SVG. A scene only supports the colors that SceneColor.Parse accepts (#rrggbb, rgb(), hsl(), CSS color names), not var(--x) or currentColor.

How the bigram is chosen

The name is split on whitespace and on the connectors used inside compound names (-, ', ., _, and their typographic variants):

  • Two or more words: the first grapheme of the first word plus the first grapheme of the last word. "John Michael Doe" gives JD, not JM. "Jean-Pierre" gives JP and "O'Brien" gives OB.
  • A single word: its first two graphemes. "John" gives Jo and "山田太郎" gives 山田.

The unit is a grapheme cluster, not a char, so an emoji or a decomposed accent counts as one. Characters that render nothing (zero-width, bidi controls, standalone combining marks) are skipped, and a name with nothing visible renders ?.

Set AvatarOptions.Bigram to bypass this entirely. It does not affect the color, which always derives from the name.

Accessibility

By default the avatar is exposed as role="img" with the bigram as its aria-label. Two options change this:

  • AccessibleLabel sets the announced text — pass the full name so it announces as "John Doe" rather than "JD".
  • IsDecorative hides the avatar from assistive technologies with aria-hidden. Use it when the avatar sits next to the name it represents, so the name is not announced twice.

Determinism

The color is hash(name) % Palette.Count, so the same name always maps to the same pair — for a fixed palette and a fixed package version. Two consequences are worth knowing before caching or persisting generated avatars:

  • The number of entries in the palette and their order are part of the mapping. Adding or removing a single AvatarColorPair re-colors nearly every name, not just the names that mapped to the changed entry.
  • The name is trimmed and normalized to Unicode Form C before hashing, so surrounding whitespace is ignored but case is not: "john doe" and "John Doe" get different colors.

Normalization requires ICU. Under InvariantGlobalization it is a no-op, so a name that is not already in Form C selects a different palette entry there than it does in a normal deployment. If you render avatars from both kinds of process and need them to agree, normalize the name yourself before calling CreateSvg.

Input handling

The generated string is always well-formed XML. Characters that the XML 1.0 specification forbids — control characters, unpaired surrogates from a name truncated mid-emoji — are removed from name and from AccessibleLabel, so an untrusted display name can be passed straight through. An explicit Bigram containing such a character is rejected with an ArgumentException instead, since that indicates a bug in the calling code.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed.  net11.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.9 0 11/15/2026
2.1.8 43 11/14/2026
2.1.7 45 11/13/2026
2.1.6 95 11/8/2026
2.1.5 167 10/28/2026
2.1.4 95 10/21/2026
2.1.3 97 10/16/2026
2.1.2 130 9/11/2026
2.1.1 129 9/6/2026
2.1.0 128 9/4/2026
2.0.2 131 8/29/2026
2.0.1 134 8/9/2026
2.0.0 152 7/5/2026
1.0.6 139 6/28/2026
1.0.5 153 6/13/2026
1.0.4 147 6/7/2026
1.0.3 137 5/23/2026
1.0.2 139 5/14/2026
1.0.1 140 4/25/2026
1.0.0 148 4/6/2026