Bitmap
Two-dimensional bit mask: alpha selection, contours and morphology.
Bitmap stores one bit per cell: a CPU mask rather than an RGBA image or GPU texture. Use it for occupied-pixel queries, contour extraction and selection dilation/erosion. A new resource has size (0, 0); allocate with Create or CreateFromImageAlpha before reading or writing cells. Integer coordinates satisfy 0 ≤ x < width and 0 ≤ y < height. Dispose an owned resource after use.
using var mask = new Bitmap();
mask.Create(new Vector2I(5, 5));
mask.SetBit(2, 2, true);
mask.GrowMask(1, new Rect2I(0, 0, 5, 5));
// mask.GetTrueBitCount() == 5Radius 1 adds the four axial neighbors, without diagonals: the neighborhood is circular. Resize scales values with nearest-neighbor sampling; it neither adds an empty border nor preserves occupied-cell coordinates.
CreateFromImageAlpha compares alpha after converting an image copy to LA8: strictly alpha > threshold. RGB does not select cells; the source image remains unchanged. Prepare a supported uncompressed image before using compressed input. ConvertToImage creates an independent opaque L8 image: false becomes black and true white, rather than transparent/opaque.
OpaqueToPolygons returns contours relative to the intersection of rect and the mask. Add that intersection position to vertices to obtain full-mask coordinates. For the entire image use new Rect2I(Vector2I.Zero, mask.GetSize()). For Sprite2D also account for centering, offset, scale and frame selection; this method creates no physics object. Contour ordering, arbitrary hole topology and suitability of every output for collision were not established by this example.
Bit and size mutations do not automatically emit Resource.Changed. If a dependent system listens to that signal, explicitly call EmitChanged after your completed operation. Data is an internal serialized representation rather than an external-file validator. Do not supply arbitrary bytes.
26 Windows headless CPU scenarios covered allocation, reads/writes, rectangle intersection, scaling, alpha, L8, dilation/erosion, valid Data transfer and a simple contour. This establishes no rendering, complex-topology, collision or other-platform acceptance.
Declarations checked against C# SDK 1.0.0. Expand a name to see declarations and documentation.
Constructors1
BitmapConstructor
public Bitmap();Creates an owned Resource with size (0, 0) and no allocated cells. Call Create/CreateFromImageAlpha before cell operations; Dispose after use.
Properties1
DataProperty
public Reckfell.Collections.Dictionary Data { get; set; }Internal Dictionary with size (Vector2I) and data (byte[]) keys. The getter creates a dictionary containing a bit-data snapshot; the setter calls Create(size) then replaces bytes without validating length or padding bits. Use only valid same-runtime representations; malformed contents can make later operations unsafe. Dispose the getter dictionary after use.
Methods13
ConvertToImageImage
public Image ConvertToImage();Creates a separate same-sized L8 Image without mipmaps. true becomes white, false black; both have opaque alpha. Updates no previously created Image and creates no GPU texture. Requires an allocated mask; Dispose the owned result.
ImageNew owned L8 Image without mipmaps, not a Texture2D.
Createvoid
public void Create(Vector2I size);Replaces dimensions and clears every bit, including existing contents at the same size. Both dimensions must be positive and their product at most Int32.MaxValue. Does not emit Changed.
| Name | Type | Default |
|---|---|---|
size | Vector2I | — |
sizePositive width/height in cells; product ≤ Int32.MaxValue.
CreateFromImageAlphavoid
public void CreateFromImageAlpha(Image image, float threshold = 0.1f);Replaces the mask with image-sized data. Converts an Image copy to LA8; a bit is true only for alpha/255 > threshold. Leaves the source unchanged; RGB brightness has no effect. Requires a nonempty Image with supported format conversion.
| Name | Type | Default |
|---|---|---|
image | Image | — |
threshold | float | 0.1f |
imageNonempty source Image; alpha is read from a converted LA8 copy.
thresholdStrict alpha threshold, normally 0…1. Equality gives false; comparison follows 8-bit conversion rather than original float precision. The argument is not clamped.
GetBitbool
public bool GetBit(int x, int y);Reads one bit at x/y. Coordinates must lie inside the mask; out-of-range access is diagnosed and returns false, so false alone does not establish valid coordinates.
| Name | Type | Default |
|---|---|---|
x | int | — |
y | int | — |
xColumn: 0 ≤ x < GetSize().X.
yRow: 0 ≤ y < GetSize().Y.
boolBit value; false is also the diagnosed invalid-coordinate fallback.
GetBitvbool
public bool GetBitv(Vector2I position);Same read as GetBit with Vector2I coordinates. Neither clamps nor wraps coordinates.
| Name | Type | Default |
|---|---|---|
position | Vector2I | — |
positionCell coordinates inside the mask, not a world position or UV.
boolBit value; also false on diagnosed invalid coordinates.
GetSizeVector2I
public Vector2I GetSize();Returns width and height in cells. A new resource before Create has size (0, 0).
Vector2IVector2I containing width and height.
GetTrueBitCountint
public int GetTrueBitCount();Counts set bits. For a valid representation this equals the occupied-cell count. The implementation counts every storage byte including final-byte padding; arbitrary Data can break that interpretation.
intSet storage-bit count; equals true-cell count for a valid mask.
GrowMaskvoid
public void GrowMask(int pixels, Rect2I rect);Positive pixels dilates true regions, negative erodes them, and 0 is a no-op. Reads a circular neighborhood from a snapshot, without cascading growth within one call. Erosion treats space outside rect as false; cells outside rect remain unchanged. Supply rect inside mask bounds and a reasonable radius: large radii are expensive and extreme int values were not accepted by this review.
| Name | Type | Default |
|---|---|---|
pixels | int | — |
rect | Rect2I | — |
pixelsInteger cell radius: positive dilates, negative erodes, 0 skips. Avoid extreme ints and large radii.
rectRegion inside mask bounds with nonnegative dimensions; outside cells remain unchanged, but erosion treats its boundary exterior as empty.
OpaqueToPolygonsReckfell.Collections.Array<Vector2[]>
public Reckfell.Collections.Array<Vector2[]> OpaqueToPolygons(Rect2I rect, float epsilon = 2f);Extracts true-cell contours in rect intersected with the mask using marching squares, then simplifies with RDP. Vertices are relative to the intersection position rather than the full mask. Empty regions yield an empty array; contours with fewer than three vertices are skipped. For contours of at least 9 vertices, epsilon is clamped to 0…half the smaller region dimension; smaller contours bypass RDP. Creates no collision object automatically.
| Name | Type | Default |
|---|---|---|
rect | Rect2I | — |
epsilon | float | 2f |
rectRectangle in mask coordinates with nonnegative dimensions; clipped to mask bounds with exclusive end.
epsilonSimplification tolerance in mask units, not a ratio or world scale. Lower values generally retain more detail; short contours may bypass RDP.
Reckfell.Collections.Array<Vector2[]>Array<Vector2[]> of contours with vertices relative to the clipped region. A result container rather than a collision Resource.
Resizevoid
public void Resize(Vector2I newSize);Scales the mask with nearest-neighbor sampling: source coordinates truncate xoldWidth/newWidth and yoldHeight/newHeight. Does not append empty rows/columns. Same dimensions are a no-op; use positive dimensions. Zero dimensions are not a safe clearing operation.
| Name | Type | Default |
|---|---|---|
newSize | Vector2I | — |
newSizePositive target dimensions for scaling, not a count of cells to append.
SetBitvoid
public void SetBit(int x, int y, bool bit);Sets or clears a cell. Coordinates must lie inside the mask; invalid ones are diagnosed without writing. Does not automatically emit Resource.Changed.
| Name | Type | Default |
|---|---|---|
x | int | — |
y | int | — |
bit | bool | — |
xColumn: 0 ≤ x < GetSize().X.
yRow: 0 ≤ y < GetSize().Y.
bitAssigned value: true occupied, false empty.
SetBitRectvoid
public void SetBitRect(Rect2I rect, bool bit);Fills the intersection of rect and mask bounds with bit. Right/bottom bounds are exclusive; a disjoint rectangle changes nothing. Assigns values rather than toggling bits.
| Name | Type | Default |
|---|---|---|
rect | Rect2I | — |
bit | bool | — |
rectRectangle in mask coordinates with nonnegative dimensions; clipped to mask bounds with exclusive end.
bitAssigned value: true occupied, false empty.
SetBitvvoid
public void SetBitv(Vector2I position, bool bit);Same mutation as SetBit using Vector2I coordinates. Does not resize the mask.
| Name | Type | Default |
|---|---|---|
position | Vector2I | — |
bit | bool | — |
positionCell coordinates inside the mask, not a world position or UV.
bitAssigned value: true occupied, false empty.