Image
Pixel rendering using half-block characters for 2x vertical resolution.
Overview
Image extends FrameworkElement and is a display-only control
with no interactive behavior. It renders a Color[,] pixel array to the terminal
using Unicode half-block characters (▀ upper half, ▄
lower half, █ full block). Each terminal cell represents two vertical
pixels — the foreground color draws the upper pixel and the background color draws
the lower pixel — achieving 2× vertical resolution compared to standard character
rendering. This means an 80×24 terminal area can display an 80×48 pixel image.
The Stretch property controls how the source image is scaled to fit the
available space, supporting four modes: None, Fill, Uniform, and UniformToFill.
Basic Example
// Build a 40x24 gradient image
var pixels = new Color[40, 24];
for (int x = 0; x < 40; x++)
for (int y = 0; y < 24; y++)
pixels[x, y] = Color.FromRgb(
(byte)(x * 255 / 39),
(byte)(y * 255 / 23),
128);
var image = new Image { Source = pixels };
Properties
| Property | Type | Default | Description |
|---|---|---|---|
| Source | Color[,]? | null | The pixel data to render. Format is Color[width, height]. |
| Stretch | Stretch | Uniform | How the image is scaled to fill the available area. One of: None, Fill, Uniform, UniformToFill. |
| Width | Size | Auto | Explicit width of the control. |
| Height | Size | Auto | Explicit height of the control. |
Stretch Modes
| Mode | Behavior |
|---|---|
| None | The image is rendered at its original pixel size with no scaling. Pixels outside the available area are clipped. |
| Fill | The image is stretched to fill the entire available area, ignoring aspect ratio. |
| Uniform | The image is scaled proportionally to fit within the available area while preserving aspect ratio. Letterboxing may appear. |
| UniformToFill | The image is scaled proportionally to completely fill the available area. Parts of the image may be clipped. |
Examples
Gradient Image
// Red-to-blue horizontal gradient, 60x30 pixels
var pixels = new Color[60, 30];
for (int x = 0; x < 60; x++)
for (int y = 0; y < 30; y++)
pixels[x, y] = Color.FromRgb(
(byte)(x * 255 / 59),
0,
(byte)(255 - x * 255 / 59));
var image = new Image
{
Source = pixels,
Stretch = Stretch.Uniform
};
Different Stretch Modes
// Same source, different stretch behaviors
var source = BuildCheckerboard(20, 20);
var none = new Image { Source = source, Stretch = Stretch.None };
var fill = new Image { Source = source, Stretch = Stretch.Fill };
var uniform = new Image { Source = source, Stretch = Stretch.Uniform };
var uniformToFill = new Image { Source = source, Stretch = Stretch.UniformToFill };
// Place in a StackPanel to compare side by side
var panel = new StackPanel { Orientation = Orientation.Horizontal };
panel.Children.Add(none);
panel.Children.Add(fill);
panel.Children.Add(uniform);
panel.Children.Add(uniformToFill);
Key Concepts
ImageextendsFrameworkElementand is display-only — it has no focus, keyboard, or mouse interaction.- The half-block technique uses Unicode characters
▀(upper half block) and▄(lower half block) to pack two vertical pixels into each terminal cell, doubling effective vertical resolution. - An 80×24 terminal area can render up to 80×48 pixels thanks to the half-block encoding.
- The
Sourceproperty accepts aColor[width, height]two-dimensional array where the first index is the x-coordinate and the second is the y-coordinate. - When
Sourceis null the control renders nothing — set it at any time to update the displayed image dynamically. - The
Stretchproperty follows WPF conventions:Uniform(default) preserves aspect ratio within bounds,Fillstretches to fill,Noneuses original size, andUniformToFillfills while preserving ratio (clipping overflow).