---
title: "Draw text on an image in C#"
url: https://recursiveai.org/oneimage/cookbook/draw-text-on-image/
description: "Draw text on an image in C# with a real font: position, alignment, wrapping, a background box and an outline. Runnable code with OneImage.Text, on any OS."
version: "1.10.4"
---

# Draw text on an image in C#

Add the `RecursiveAI.OneImage.Text` package, load a font file into a `FontCollection`, and call `DrawText` with the text, a `TextOptions` saying where it goes, and a color. Text is shaped with OpenType, so kerning, ligatures, right-to-left and complex scripts come out right. The program below captions NASA’s “Blue Marble” photograph (public domain) in Noto Sans.

```shell
dotnet new console -o DrawText && cd DrawText
dotnet add package RecursiveAI.OneImage.Text --version 1.10.4
curl -L -o photo.jpg \
  https://images-assets.nasa.gov/image/as17-148-22727/as17-148-22727~orig.jpg
fonts=https://github.com/notofonts/notofonts.github.io/raw/main/fonts
curl -L -o NotoSans-Regular.ttf $fonts/NotoSans/hinted/ttf/NotoSans-Regular.ttf
```

OneImage needs the .NET 10 SDK. Put this in `Program.cs` and run `dotnet run`:

```csharp
using OneImage;
using OneImage.Drawing;
using OneImage.Text;
using Path = OneImage.Drawing.Path;

Image photo = Image.Load("photo.jpg").Resize(width: 1200);

Font font = new FontCollection().Add("NotoSans-Regular.ttf").CreateFont(44);
var options = new TextOptions(font)
{
    // The origin is the bottom center of the text block, 40 px above the edge.
    Origin = new(photo.Width / 2, photo.Height - 40),
    HorizontalAlignment = HorizontalAlignment.Center,
    VerticalAlignment = VerticalAlignment.Bottom,
    TextAlignment = TextAlignment.Center,
    WrappingLength = 1000,   // wrap lines wider than 1000 px
};
string caption = "The Blue Marble, photographed from Apollo 17 on its way to the Moon";

// Measure the text to put a translucent box behind it.
var box = TextMeasurer.MeasureBounds(caption, options);
Console.WriteLine($"{TextMeasurer.CountLines(caption, options)} lines, "
                + $"{box.Width:0}x{box.Height:0} px");

Path back = Path.RoundedRectangle(box.X - 24, box.Y - 16,
                                  box.Width + 48, box.Height + 32, radius: 12);
photo.Fill(new Rgba32(0, 0, 0, 160), back)
     .DrawText(caption, options, new Rgba32(255, 255, 255, 255))
     .Save("captioned.jpg");
Console.WriteLine("Saved captioned.jpg");
```

```text
2 lines, 972x88 px
Saved captioned.jpg
```

`Origin` is in pixels from the top-left corner, and the two alignments say which point of the text block it is, so you don’t have to measure text to center or right-align it. `WrappingLength` breaks lines at word boundaries.

## Outlined text

To keep text readable over both light and dark areas without a box, draw it with a `Brush` for the fill and a `Pen` for the outline:

```csharp
using OneImage;
using OneImage.Drawing;
using OneImage.Text;

Image photo = Image.Load("photo.jpg").Resize(width: 1200);
Font font = new FontCollection().Add("NotoSans-Regular.ttf").CreateFont(36);

var options = new TextOptions(font)
{
    Origin = new(photo.Width - 30, photo.Height - 30),
    HorizontalAlignment = HorizontalAlignment.Right,
    VerticalAlignment = VerticalAlignment.Bottom,
};
photo.DrawText("Photo: NASA", options,
               Brush.Solid(new Rgba32(255, 255, 255, 220)),
               new Pen(Brush.Solid(new Rgba32(0, 0, 0, 160)), width: 2))
     .Save("credited.jpg");
Console.WriteLine("Saved credited.jpg");
```

```text
Saved credited.jpg
```

## Limits

- **No fonts are bundled.** Installed fonts are available through `SystemFonts`, but containers usually have none; a TrueType, OpenType, WOFF or WOFF2 file you ship gives the same output everywhere.
- **Sizes are in pixels.** Scale the font size from the image width if your images vary in size.
- **Emoji and missing characters** need a font that has them; add one with `FallbackFontFamilies`.

For a translucent mark across the whole image, see [Add a watermark](https://recursiveai.org/oneimage/cookbook/add-watermark/). Rich text, vertical layout and hinting are in the [Text docs](https://recursiveai.org/oneimage/docs/text/).
