CUR
CUR is the Windows cursor format. It is closely related to ICO, but it carries cursor-specific hotspot information so the runtime knows which pixel is the active click point.
ImageSharp exposes CUR-specific APIs through CurEncoder, CurMetadata, and CurFrameMetadata.
Format Characteristics
CUR is best thought of as a cursor container rather than a normal image file format.
CUR shares much of the icon-container shape with ICO, but cursor files add hotspot coordinates. The hotspot is the active point of the cursor: for an arrow it is normally the tip; for a crosshair it may be the center. If the hotspot is wrong, the image can look correct while clicking and hit testing feel wrong.
Like ICO, a CUR file can contain multiple embedded images for different sizes. Consumers can choose a frame based on display scale or cursor size. Hotspot metadata is per frame, so every embedded cursor image needs correct hotspot coordinates.
A few practical implications:
- Existing CUR files can contain one or more cursor images.
- Cursor-specific metadata lives primarily on
CurFrameMetadata. HotspotXandHotspotYare the key extra values that distinguish cursor assets from icons.- CUR is useful when you need Windows cursor output with hotspot metadata, not when you need a general-purpose image format.
Save as CUR
Use CurEncoder when you want Windows cursor output:
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Cur;
using SixLabors.ImageSharp.PixelFormats;
using Image<Rgba32> image = Image.Load<Rgba32>("cursor-source.png");
CurFrameMetadata frameMetadata = image.Frames.RootFrame.Metadata.GetCurMetadata();
frameMetadata.HotspotX = 4;
frameMetadata.HotspotY = 4;
image.Save("pointer.cur", new CurEncoder());
CUR Frame Metadata
The most useful CUR-specific values live on CurFrameMetadata:
HotspotXandHotspotYcontrol the cursor hotspot coordinates.EncodingWidthandEncodingHeightdescribe the encoded cursor dimensions for that frame.CompressionandBmpBitsPerPixeldescribe how the frame is stored.
CurMetadata mirrors the root frame's compression, bit depth, and color-table information at the image level.
Treat hotspot coordinates as part of the user interaction contract. They should be chosen from the cursor design, not copied blindly from another size unless the coordinate scales correctly.
Read CUR Metadata
Use Image.Identify() when you want cursor metadata without a full decode:
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Cur;
ImageInfo info = Image.Identify("pointer.cur");
Console.WriteLine($"Embedded cursor images: {info.FrameMetadataCollection.Count}");
CurMetadata curMetadata = info.Metadata.GetCurMetadata();
CurFrameMetadata firstFrame = info.FrameMetadataCollection[0].GetCurMetadata();
Console.WriteLine(curMetadata.Compression);
Console.WriteLine(firstFrame.HotspotX);
Console.WriteLine(firstFrame.HotspotY);
When to Use CUR
CUR is usually worth considering when:
- You need a Windows cursor file.
- The hotspot position is part of the asset contract.
CUR is usually a poor fit when:
- You are storing a normal image rather than a cursor asset.
- You want broad compatibility outside Windows cursor workflows.
For Windows icon assets without cursor hotspots, see ICO.
Practical Guidance
- Treat hotspot coordinates as part of the cursor asset, not incidental metadata.
- Validate all embedded frames when generating multi-size cursor files.
- Use CUR only when the output is meant to behave as a cursor.
- Use ICO, PNG, or another ordinary image format when hotspot metadata is not required.