/// <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 DirectImage image, int x, int y, ColorRgba32 fillColor) { bool isModified = false; var replaceColor = image.GetPixel(x, y); if (fillColor.Color == replaceColor.Color) { 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.Color == replaceColor.Color) { isModified = true; image.SetPixel(nodePosition.x, nodePosition.y, fillColor); 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); }
public static MagitekResult CopyPixels(DirectImage source, DirectImage dest, Point sourceStart, Point destStart, int copyWidth, int copyHeight) { var dimensionResult = CanCopyPixelDimensions(source, dest, sourceStart, destStart, copyWidth, copyHeight); if (dimensionResult.Value is MagitekResult.Failed) { return(dimensionResult); } if (ImageRegionContainsInvalidElements(source, sourceStart, copyWidth, copyHeight)) { return(new MagitekResult.Failed($"Source image copy region contains blank elements")); } if (ImageRegionContainsInvalidElements(dest, destStart, copyWidth, copyHeight)) { return(new MagitekResult.Failed($"Destination image paste region contains blank elements")); } for (int y = 0; y < copyHeight; y++) { for (int x = 0; x < copyWidth; x++) { var color = source.GetPixel(x + sourceStart.X, y + sourceStart.Y); dest.SetPixel(x + destStart.X, y + destStart.Y, color); } } return(MagitekResult.SuccessResult); }
private static void ApplyExactColorRemapPixels(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); dest.SetPixel(x + destStart.X, y + destStart.Y, color); } } }
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); }
private static MagitekResult CanExactColorRemapPixels(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); var result = dest.CanSetPixel(x + destStart.X, y + destStart.Y, color); if (result.Value is MagitekResult.Failed) { return(result); } } } return(MagitekResult.SuccessResult); }
public override ColorRgba32 GetPixel(int x, int y) => _directImage.GetPixel(x, y);