ImageGlass.SDK
1.0.100266
dotnet add package ImageGlass.SDK --version 1.0.100266
NuGet\Install-Package ImageGlass.SDK -Version 1.0.100266
<PackageReference Include="ImageGlass.SDK" Version="1.0.100266" />
<PackageVersion Include="ImageGlass.SDK" Version="1.0.100266" />
<PackageReference Include="ImageGlass.SDK" />
paket add ImageGlass.SDK --version 1.0.100266
#r "nuget: ImageGlass.SDK, 1.0.100266"
#:package ImageGlass.SDK@1.0.100266
#addin nuget:?package=ImageGlass.SDK&version=1.0.100266
#tool nuget:?package=ImageGlass.SDK&version=1.0.100266
ImageGlass SDK
The official development kit for extending ImageGlass 10. ImageGlass.SDK is a single .NET 10 class library that defines the public contracts for the two ways you can extend ImageGlass.
What you can build
| You want to… | Build… | How it runs |
|---|---|---|
| Add support for an image format ImageGlass can't open yet (a new or proprietary codec) | Plugin | Native, in-process codec loaded through a versioned C ABI |
| Add a feature that reacts to the user — read pixels under the cursor, inspect the current photo, drive the viewer, run host commands | Tool | Out-of-process program ImageGlass launches and drives over a named pipe |
A few concrete examples of what the SDK makes possible:
- A codec that decodes a custom or rare image format and renders it like any built-in format — still or animated.
- A color picker that reports the RGBA value under the user's click.
- A batch/automation tool that watches photo navigation and runs actions against the current image, selection, or theme.
The two surfaces are independent — pick the one that matches what you want to build. See Samples for working, end-to-end examples of each.
Installation
Install the package from NuGet:
dotnet add package ImageGlass.SDK
The library targets net10.0 and depends only on SkiaSharp. It is AOT- and trim-compatible, so your plugin or tool can publish with Native AOT.
Building this repository
Requires the .NET 10 SDK.
dotnet build source/ImageGlass.SDK.slnx
Supported platforms: x64, ARM64, AnyCPU.
Samples
The samples/ folder contains complete, runnable projects — the fastest way to see each extension surface end to end. Each sample has its own README with build, install, and registration steps.
| Sample | Surface | What it shows |
|---|---|---|
| Base64Codec | Plugin (codec) | A tiny cross-platform native codec that adds .b64 support — reads a base64-encoded image, decodes it with SkiaSharp into a 32bpp BGRA buffer, and manages pixel-buffer memory through the ABI. Publishes as a Native AOT shared library. |
| ConsoleColorPicker | Tool | A console tool that connects over the named pipe, reads metadata of the current photo, follows photo navigation, and logs the RGBA value of the pixel the user clicks in the viewer via opt-in pointer events. |
🟢 Building a Codec Plugin
Plugins run in-process and communicate with the host through function-pointer tables (a C ABI), so they can be written in any language that can export a C entry point and produce a native shared library.
A plugin ships as a folder containing the native library plus an igplugin.json manifest:
{
"id": "Plugin_MyCodec",
"name": "My Codec",
"version": "1.0.0",
"author": "You",
"kind": "Codec",
"executable": "MyCodec.dll", // MyCodec.so / MyCodec.dylib on other platforms
"supportedExtensions": ".foo;.bar" // optional; overrides the plugin-reported list
}
The host loads the library and calls the single required export:
const IGPluginApi* ig_plugin_get_api(int hostAbiVersion, const IGHostApi* hostApi);
It returns an IGPluginApi table (plugin identity + GetCodec/Initialize/Shutdown/SelfTest). Each codec then exposes an IGCodecApi table: capability reporting, extension/signature matching, LoadMetadata, DecodeStaticRaster, and optional animation entry points.
Key contracts to honor:
- ABI version — encoded as
MAJOR * 1_000_000 + MINOR * 1_000 + PATCH(IGNativeAbi.IG_PLUGIN_ABI_VERSION). The host rejects plugins whose major version does not match. - Memory ownership — the plugin allocates pixel/animation buffers; the host calls back into the plugin's
FreePixelBuffer/FreeAnimationInfoto release them.FreePixelBuffermust be thread-safe — it may be invoked from any thread when the host disposes the image. - Animation — decoded animation frames must be fully composed RGBA at full canvas size. The host does not perform sub-rect composition or disposal/blend replay, so codecs like GIF/APNG must composite internally.
- Cancellation — long operations receive an opaque cancellation token; poll
IGHostCoreApi.IsCancellationRequestedand returnIGStatus.Canceledwhen set.
🟢 Building a Tool
Tools run out-of-process. Subclass ToolBase, then start it from your program's entry point:
using ImageGlass.SDK.Tools;
public sealed class MyTool : ToolBase
{
public override string ToolId => "MyTool"; // must match igconfig.json
protected override Task OnExecuteAsync(CancellationToken ct)
{
// Triggered by the host. Talk back through HostApi.
return Task.CompletedTask;
}
protected override void OnPhotoChanged(PhotoChangedEventArgs e)
{
// React to the user navigating to another photo.
}
}
public static class Program
{
public static Task Main(string[] args) => new MyTool().RunAsync(args);
}
ImageGlass launches the tool with a --pipe <name> argument; RunAsync connects to the host and runs the message loop until shutdown.
- Host → tool events arrive as
OnXxxoverrides (OnInitializedAsync,OnExecuteAsync,OnPhotoChanged,OnThemeChanged,OnSelectionChanged, …). - Tool → host calls go through
HostApi(IToolHostProxy): read pixels, get the full pixel buffer (via a memory-mapped file), query photo metadata and the photo list, get/set the selection, run named ImageGlass API methods, and read theme info. - Real-time pointer/selection/frame events are opt-in via
HostApi.SubscribeEventsAsync. - Register the tool with ImageGlass through an
igconfig.jsonentry whoseToolIdmatches yourToolBase.ToolId.
Passing the current file to the tool
In the Arguments field of the igconfig.json entry you can use the <file> macro. ImageGlass replaces it with the full path of the currently viewed image when it launches the tool:
"Tools": [
{
"ToolId": "Tool_MyTool",
"ToolName": "My Tool",
"Executable": "C:\\path\\to\\MyTool.exe",
"Arguments": "--input \"<file>\"", // expands to: --input "C:\Photos\my image.png"
"IsIntegrated": true,
"Hotkeys": ["Alt+1"]
}
]
IsIntegrated—truemakes this an SDK tool: ImageGlass launches the process with the--pipe <name>argument and wires up the two-wayHostApiproxy, so the tool can useToolBase/HostApito talk to the host. Set itfalse(or omit it) for a plain external program that is just launched with its arguments and gets no pipe connection.Hotkeys— an array of key-combination strings that run the tool when pressed in ImageGlass (e.g.["Alt+1"],["K"]). Use an empty array[]if you don't want a shortcut.
<file> expands to the path without quotes — wrap it yourself as "<file>" when the path may contain spaces. The expanded value arrives in your tool's args (the string[] passed to Main / RunAsync).
Set EnableDebug = true and provide a DebugLog sink before calling RunAsync to trace pipe connection and message dispatch when a tool appears to "do nothing".
License
MIT © 2026 Duong Dieu Phap
| Product | Versions 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. |
-
net10.0
- SkiaSharp (>= 3.119.4)
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 |
|---|---|---|
| 1.0.100266 | 97 | 5/30/2026 |