Exemple #1
0
    /// <summary>
    /// Fills the surrounding, contiguous color area with a new color
    /// </summary>
    /// <param name="x">x-coordinate to start at in pixel coordinates</param>
    /// <param name="y">y-coordinate to start at in pixel coordinates</param>
    /// <param name="fillIndex">Palette index to fill with</param>
    /// <returns>True if any pixels were modified</returns>
    public static bool FloodFill(this IndexedImage image, int x, int y, byte fillIndex)
    {
        bool isModified      = false;
        var  replaceIndex    = image.GetPixel(x, y);
        var  startingPalette = image.GetElementAtPixel(x, y).Value.Palette;

        if (fillIndex == replaceIndex)
        {
            return(false);
        }

        var openNodes = new Stack <(int x, int y)>();

        openNodes.Push((x, y));

        while (openNodes.Count > 0)
        {
            var nodePosition = openNodes.Pop();

            if (nodePosition.x >= 0 && nodePosition.x < image.Width && nodePosition.y >= 0 && nodePosition.y < image.Height)
            {
                var nodeColor = image.GetPixel(nodePosition.x, nodePosition.y);
                if (nodeColor == replaceIndex)
                {
                    var destPalette = image.GetElementAtPixel(nodePosition.x, nodePosition.y).Value.Palette;
                    if (ReferenceEquals(startingPalette, destPalette))
                    {
                        isModified = true;
                        image.SetPixel(nodePosition.x, nodePosition.y, fillIndex);
                        openNodes.Push((nodePosition.x - 1, nodePosition.y));
                        openNodes.Push((nodePosition.x + 1, nodePosition.y));
                        openNodes.Push((nodePosition.x, nodePosition.y - 1));
                        openNodes.Push((nodePosition.x, nodePosition.y + 1));
                    }
                }
            }
        }

        return(isModified);
    }
Exemple #2
0
    private static MagitekResult CanRemapByExactPaletteColors(DirectImage source, IndexedImage dest, Point sourceStart, Point destStart, int copyWidth, int copyHeight)
    {
        for (int y = 0; y < copyHeight; y++)
        {
            for (int x = 0; x < copyWidth; x++)
            {
                var color = source.GetPixel(x + sourceStart.X, y + sourceStart.Y);
                if (dest.CanSetPixel(x + destStart.X, y + destStart.Y, color).Value is MagitekResult.Failed)
                {
                    var palName = dest.GetElementAtPixel(x + destStart.X, y + destStart.Y)?.Palette?.Name ?? "Undefined";
                    return(new MagitekResult.Failed($"Destination image at (x: {destStart.X}, y: {destStart.Y}) with element palette '{palName}' could not be set to the source color ({color.A}, {color.R}, {color.G}, {color.B})"));
                }
            }
        }

        return(MagitekResult.SuccessResult);
    }
Exemple #3
0
    private static MagitekResult CanRemapByExactIndex(IndexedImage source, IndexedImage dest, Point sourceStart, Point destStart, int copyWidth, int copyHeight)
    {
        for (int y = 0; y < copyHeight; y++)
        {
            for (int x = 0; x < copyWidth; x++)
            {
                var el = source.GetElementAtPixel(sourceStart.X + x, sourceStart.Y + y);
                if (el is ArrangerElement element)
                {
                    if ((1 << element.Codec.ColorDepth) < dest.GetPixel(destStart.X + x, destStart.Y + y))
                    {
                        return(new MagitekResult.Failed($"Destination image contains a palette index too large to map to the source image pixels at destination position ({destStart.X + x}, {destStart.Y + y}) and source position ({sourceStart.X + x}, {sourceStart.Y + y})"));
                    }
                }
            }
        }

        return(MagitekResult.SuccessResult);
    }