Add crop functionality to DirectBitmap

This commit is contained in:
ds5678 2025-10-10 01:45:01 -07:00
parent 3124e0599a
commit fca21ad09c
3 changed files with 42 additions and 0 deletions

View File

@ -75,6 +75,13 @@ public abstract class DirectBitmap
Transpose();
}
public DirectBitmap Crop(Range xRange, Range yRange)
{
return Crop(xRange, yRange, 0..Depth);
}
public abstract DirectBitmap Crop(Range xRange, Range yRange, Range zRange);
public abstract DirectBitmap DeepClone();
public void Save(Stream stream, ImageExportFormat format)

View File

@ -70,6 +70,10 @@ public sealed class DirectBitmap<TColor, TChannel> : DirectBitmap
public override void Transpose()
{
if (Width != Height)
{
throw new InvalidOperationException("Only square images can be transposed.");
}
int layerSize = Width * Height;
Span<TColor> pixels = Pixels;
for (int depthIndex = 0; depthIndex < Depth; depthIndex++)
@ -86,6 +90,35 @@ public sealed class DirectBitmap<TColor, TChannel> : DirectBitmap
}
}
public new DirectBitmap<TColor, TChannel> Crop(Range xRange, Range yRange)
{
return (DirectBitmap<TColor, TChannel>)base.Crop(xRange, yRange);
}
public override DirectBitmap<TColor, TChannel> Crop(Range xRange, Range yRange, Range zRange)
{
(int xOffset, int xLength) = xRange.GetOffsetAndLength(Width);
(int yOffset, int yLength) = yRange.GetOffsetAndLength(Height);
(int zOffset, int zLength) = zRange.GetOffsetAndLength(Depth);
if (xLength == Width && yLength == Height && zLength == Depth)
{
return DeepClone();
}
byte[] croppedData = new byte[xLength * yLength * zLength * PixelSize];
int layerSize = Width * Height;
int croppedLayerSize = xLength * yLength;
for (int z = 0; z < zLength; z++)
{
for (int y = 0; y < yLength; y++)
{
int sourceIndex = (z + zOffset) * layerSize + (y + yOffset) * Width + xOffset;
int destinationIndex = z * croppedLayerSize + y * xLength;
Buffer.BlockCopy(Data, sourceIndex * PixelSize, croppedData, destinationIndex * PixelSize, xLength * PixelSize);
}
}
return new DirectBitmap<TColor, TChannel>(xLength, yLength, zLength, croppedData);
}
public override DirectBitmap<TColor, TChannel> DeepClone()
{
byte[] data = new byte[Data.Length];

View File

@ -24,6 +24,8 @@ internal sealed class EmptyDirectBitmap : DirectBitmap
{
}
public override EmptyDirectBitmap Crop(Range xRange, Range yRange, Range zRange) => this;
public override EmptyDirectBitmap DeepClone() => this;
public override void SaveAsBmp(Stream stream)