Этап 2

This commit is contained in:
2026-03-29 15:34:33 +03:00
parent 09d52aa973
commit 08b9039b58
19 changed files with 872 additions and 3 deletions

View File

@@ -0,0 +1,13 @@
namespace Minint.Core.Services;
public interface IBmpExporter
{
/// <summary>
/// Exports a composited ARGB pixel buffer as a 32-bit BMP file.
/// </summary>
/// <param name="stream">Output stream.</param>
/// <param name="pixels">Pixel data packed as 0xAARRGGBB, row-major.</param>
/// <param name="width">Image width.</param>
/// <param name="height">Image height.</param>
void Export(Stream stream, uint[] pixels, int width, int height);
}

View File

@@ -0,0 +1,13 @@
using Minint.Core.Models;
namespace Minint.Core.Services;
public interface ICompositor
{
/// <summary>
/// Composites all visible layers of <paramref name="document"/> into a flat RGBA buffer.
/// Result is packed as ARGB (0xAARRGGBB) per pixel, row-major, length = width * height.
/// Layers are blended bottom-to-top with alpha compositing.
/// </summary>
uint[] Composite(MinintDocument document, int width, int height);
}

View File

@@ -0,0 +1,25 @@
using Minint.Core.Models;
namespace Minint.Core.Services;
public interface IDrawingService
{
/// <summary>
/// Applies a circular brush stroke at (<paramref name="cx"/>, <paramref name="cy"/>)
/// with the given <paramref name="radius"/>. Sets affected pixels to <paramref name="colorIndex"/>.
/// </summary>
void ApplyBrush(MinintLayer layer, int cx, int cy, int radius, int colorIndex, int width, int height);
/// <summary>
/// Applies a circular eraser at (<paramref name="cx"/>, <paramref name="cy"/>)
/// with the given <paramref name="radius"/>. Sets affected pixels to index 0 (transparent).
/// </summary>
void ApplyEraser(MinintLayer layer, int cx, int cy, int radius, int width, int height);
/// <summary>
/// Returns the set of pixel coordinates affected by a circular brush/eraser
/// centered at (<paramref name="cx"/>, <paramref name="cy"/>) with given <paramref name="radius"/>.
/// Used for tool preview overlay.
/// </summary>
List<(int X, int Y)> GetBrushMask(int cx, int cy, int radius, int width, int height);
}

View File

@@ -0,0 +1,12 @@
using Minint.Core.Models;
namespace Minint.Core.Services;
public interface IFloodFillService
{
/// <summary>
/// Flood-fills a contiguous region of identical color starting at (<paramref name="x"/>, <paramref name="y"/>)
/// with <paramref name="newColorIndex"/>. Uses 4-connectivity (up/down/left/right).
/// </summary>
void Fill(MinintLayer layer, int x, int y, int newColorIndex, int width, int height);
}

View File

@@ -0,0 +1,29 @@
using Minint.Core.Models;
namespace Minint.Core.Services;
public interface IFragmentService
{
/// <summary>
/// Copies a rectangular region from one document/layer to another.
/// Palette colors are merged: missing colors are added to the destination palette.
/// </summary>
/// <param name="srcDoc">Source document.</param>
/// <param name="srcLayerIndex">Index of the source layer.</param>
/// <param name="srcX">Source rectangle X origin.</param>
/// <param name="srcY">Source rectangle Y origin.</param>
/// <param name="regionWidth">Width of the region to copy.</param>
/// <param name="regionHeight">Height of the region to copy.</param>
/// <param name="dstDoc">Destination document.</param>
/// <param name="dstLayerIndex">Index of the destination layer.</param>
/// <param name="dstX">Destination X origin.</param>
/// <param name="dstY">Destination Y origin.</param>
/// <param name="containerWidth">Container width (shared by both docs).</param>
/// <param name="containerHeight">Container height (shared by both docs).</param>
void CopyFragment(
MinintDocument srcDoc, int srcLayerIndex,
int srcX, int srcY, int regionWidth, int regionHeight,
MinintDocument dstDoc, int dstLayerIndex,
int dstX, int dstY,
int containerWidth, int containerHeight);
}

View File

@@ -0,0 +1,13 @@
namespace Minint.Core.Services;
public interface IGifExporter
{
/// <summary>
/// Exports multiple frames as an animated GIF.
/// </summary>
/// <param name="stream">Output stream.</param>
/// <param name="frames">Sequence of (ARGB pixels, delay in ms) per frame.</param>
/// <param name="width">Frame width.</param>
/// <param name="height">Frame height.</param>
void Export(Stream stream, IReadOnlyList<(uint[] Pixels, uint DelayMs)> frames, int width, int height);
}

View File

@@ -0,0 +1,20 @@
using Minint.Core.Models;
namespace Minint.Core.Services;
public interface IImageEffectService
{
/// <summary>
/// Adjusts contrast of the document by modifying palette colors.
/// <paramref name="factor"/> > 1 increases contrast, &lt; 1 decreases.
/// Index 0 (transparent) is not modified.
/// </summary>
void AdjustContrast(MinintDocument document, float factor);
/// <summary>
/// Converts the document to grayscale by modifying palette colors.
/// Uses ITU-R BT.601 luminance: gray = 0.299R + 0.587G + 0.114B.
/// Index 0 (transparent) is not modified.
/// </summary>
void ToGrayscale(MinintDocument document);
}

View File

@@ -0,0 +1,17 @@
using Minint.Core.Models;
namespace Minint.Core.Services;
public interface IMinintSerializer
{
/// <summary>
/// Serializes the container to a binary .minint stream.
/// </summary>
void Write(Stream stream, MinintContainer container);
/// <summary>
/// Deserializes a .minint stream into a container.
/// Throws <see cref="InvalidDataException"/> on format/validation errors.
/// </summary>
MinintContainer Read(Stream stream);
}

View File

@@ -0,0 +1,23 @@
using Minint.Core.Models;
namespace Minint.Core.Services;
public interface IPaletteService
{
/// <summary>
/// Returns the index of <paramref name="color"/> in the document palette.
/// If the color is not present, appends it and returns the new index.
/// </summary>
int EnsureColor(MinintDocument document, RgbaColor color);
/// <summary>
/// Finds index of an exact color match, or returns -1 if not found.
/// </summary>
int FindColor(MinintDocument document, RgbaColor color);
/// <summary>
/// Removes unused colors from the palette and remaps all layer pixel indices.
/// Index 0 (transparent) is always preserved.
/// </summary>
void CompactPalette(MinintDocument document);
}

View File

@@ -0,0 +1,28 @@
using Minint.Core.Models;
namespace Minint.Core.Services;
public enum PatternType
{
Checkerboard,
HorizontalGradient,
VerticalGradient,
HorizontalStripes,
VerticalStripes,
ConcentricCircles,
Tile
}
public interface IPatternGenerator
{
/// <summary>
/// Generates a new document with a single layer filled with the specified pattern.
/// </summary>
/// <param name="type">Pattern type.</param>
/// <param name="width">Image width in pixels.</param>
/// <param name="height">Image height in pixels.</param>
/// <param name="colors">Colors to use (interpretation depends on pattern type).</param>
/// <param name="param1">Primary parameter: cell/stripe size, ring width, etc.</param>
/// <param name="param2">Secondary parameter (optional, pattern-dependent).</param>
MinintDocument Generate(PatternType type, int width, int height, RgbaColor[] colors, int param1, int param2 = 0);
}