Skip to main content

Graphics

TinyCLR has two graphics options for drawing on a display:

  • The graphics engine (this page) — the standard drawing primitives: shapes, text, bitmaps, color management, and clipping, on top of a configured display. Available on SC20xxx hardware. There's no built-in font — text draws with font resources embedded in your project (Font Support).
  • BasicGraphics — a lightweight managed library with a built-in font. It runs on every device, but it's mainly for small chips without native display support — on SC13xxx hardware it's the only option.

This page covers the graphics engine's drawing API; BasicGraphics is summarized below, with its full reference in Extended Features. For setting up the display itself (parallel RGB timing, SPI controllers, etc.), see Displays.

NuGet package: GHIElectronics.TinyCLR.Drawing. Add the display-specific packages from Displays for the underlying panel.

Which do I need?

Beyond the drawing libraries above, TinyCLR also has a full UI framework — pick by what you're building:

  • Graphics (this page) — immediate-mode drawing. You call DrawLine, FillEllipse, DrawString and push the result to the screen yourself: the quickest way to draw simple shapes, text, and bitmaps, ideal for gauges, dashboards, and custom visuals. Both libraries fit here — the graphics engine on SC20xxx, BasicGraphics on small chips.
  • User Interface — a WPF-style framework on the same display backends: windows, buttons, lists, layouts, events, and touch handling, with screens laid out visually in the TinyCLR UI Designer. Pick it when you're building screens a user interacts with rather than drawing visuals yourself.

Try it: the Create Graphics tutorial bounces a ball and centers text on screen with both drawing libraries in about 25 minutes.

Drawing primitives

The core shapes use Graphics methods with Pen and Brush arguments:

  • Graphics.DrawLine, Graphics.DrawRectangle, Graphics.DrawEllipse — outlines.
  • Graphics.FillRectangle, Graphics.FillEllipse — filled shapes.
  • Graphics.SetPixel — single-pixel drawing.
  • Graphics.DrawString — text rendering using converted .tcfnt fonts.
  • Graphics.DrawImage — bitmap blitting.

Useful helper methods

MethodDescription
TileImageRepeat an image as a fill pattern across an area.
DrawTextInRectConfine text to a rectangle with justify and word-wrap options.
SetClippingRectangleRestrict subsequent drawing to a rectangular region.
MakeTransparentMake a specific color transparent in an image (alpha = 0).
Scale9ImageScale a bitmap with stretchable regions and opacity control.
MeasureStringCompute the pixel size of a string in a given font.
RotateImageRotate a bitmap.

BasicGraphics

BasicGraphics is a simpler, pure-managed drawing library with a built-in font — SetPixel, DrawLine, DrawRectangle, DrawCircle, DrawString, and friends. It runs on every device, but it's mainly for small chips without native display support: the full graphics engine isn't available on SC13xxx hardware, so BasicGraphics is the drawing option there. It also works on SC20xxx when the full engine is more than you need.

Part 1 of the Create Graphics tutorial is built on it; see Extended Features → BasicGraphics for the full reference.

Getting a Graphics surface

How you get a drawing surface depends on the underlying display:

  • Native (parallel RGB) displaysGraphics.FromHdc(displayController.Hdc). Pixels are written into the DMA-refreshed framebuffer; the display updates continuously.
  • Virtual (SPI / I²C / network) displaysGraphics.FromImage(new Bitmap(width, height)). You draw into a RAM bitmap, and Graphics.OnFlushEvent fires with the pixel data when you call Flush(). Wire that event to your display driver's DrawBuffer method.

The example below targets the SCM20260D 4.3" native display setup — once displayController is configured and enabled, the drawing code is the same regardless of which panel is underneath.

using System.Drawing;

var screen = Graphics.FromHdc(displayController.Hdc);

var image = Resources.GetBitmap(Resources.BitmapResources.smallJpegBackground);
var font = Resources.GetFont(Resources.FontResources.small);

screen.Clear();

screen.FillEllipse(new SolidBrush(Color.FromArgb(255, 255, 0, 0)), 0, 0, 240, 136);
screen.FillEllipse(new SolidBrush(Color.FromArgb(255, 0, 0, 255)), 240, 0, 240, 136);
screen.FillEllipse(new SolidBrush(Color.FromArgb(128, 0, 255, 0)), 120, 0, 240, 136);

screen.DrawImage(image, 216, 122);

screen.DrawRectangle(new Pen(Color.Yellow), 10, 150, 140, 100);
screen.DrawEllipse(new Pen(Color.Purple), 170, 150, 140, 100);
screen.FillRectangle(new SolidBrush(Color.Teal), 330, 150, 140, 100);

screen.DrawLine(new Pen(Color.White), 10, 271, 470, 271);
screen.SetPixel(240, 200, Color.White);

screen.DrawString("Hello world!", font, new SolidBrush(Color.Blue), 210, 255);

screen.Flush();

For a virtual display, swap the first line for Graphics.FromImage(new Bitmap(SCREEN_WIDTH, SCREEN_HEIGHT)) and wire Graphics.OnFlushEvent to push the rendered bitmap to the SPI driver — see Displays → Virtual displays for the controller setup.

Auto-scaling to the display

DisplayController.ActiveConfiguration exposes the width and height at runtime — useful for writing code that adapts to whichever panel is connected:

screen.DrawLine(new Pen(Color.Red), 0, 0,
displayController.ActiveConfiguration.Width - 1,
displayController.ActiveConfiguration.Height - 1);

2D matrix copy

Array.Copy2D is a fast native bulk-copy useful for cropping a rectangle out of a bitmap. groupSize is the number of bytes per pixel — TinyCLR's internal 5:6:5 RGB format is 2 bytes per pixel, so groupSize = 2.

var groupSize = 2;
var screenWidth = 160;
var screenHeight = 128;

var screen = new Bitmap(screenWidth, screenHeight);
var cropped = new byte[80 * 80 * 2];

Array.Copy2D(screen.GetBitmap(), cropped, x: 5, y: 5, width: 80, height: 80, screenWidth, groupSize);

See also

  • Displays — panel setup (parallel, SPI, character)
  • Image Decoders — JPG, GIF, BMP loading and saving
  • Font Support — converting and using fonts
  • Encoding & Decoding — converting between color spaces (5:6:5 ↔ 8:8:8 etc.)
  • VNC — remote framebuffer output as a virtual-display destination

API reference

NamespaceDescription
GHIElectronics.TinyCLR.DrawingBitmap, graphics context, and drawing primitives
GHIElectronics.TinyCLR.Devices.DisplayDisplay controller for flushing bitmaps to the screen