//private static MagitekResult CanRemapByAnyIndex(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++) // { // } // } // return MagitekResult.SuccessResult; //} private static void ApplyRemapByExactIndex(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 index = source.GetPixel(x + sourceStart.X, y + sourceStart.Y); dest.SetPixel(x + destStart.X, y + destStart.Y, index); } } }
/// <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); }
/// <summary> /// Tries to set the palette to the ArrangerElement containing the specified pixel coordinate /// </summary> /// <param name="x">x-coordinate in pixel coordinates</param> /// <param name="y">y-coordinate in pixel coordinates</param> /// <param name="pal">Palette to be set, if possible</param> /// <returns></returns> public static MagitekResult TrySetPalette(this IndexedImage image, int x, int y, Palette pal) { if (x + image.Left >= image.Arranger.ArrangerPixelSize.Width || y + image.Top >= image.Arranger.ArrangerPixelSize.Height) { return(new MagitekResult.Failed($"Cannot assign the palette because the location ({x}, {y}) is outside of the arranger " + $"'{image.Arranger.Name}' bounds ({image.Arranger.ArrangerPixelSize.Width}, {image.Arranger.ArrangerPixelSize.Height})")); } var el = image.Arranger.GetElementAtPixel(x + image.Left, y + image.Top); if (el is ArrangerElement element) { if (ReferenceEquals(pal, element.Palette)) { return(MagitekResult.SuccessResult); } int maxIndex = 0; for (int pixelY = element.Y1; pixelY <= element.Y2; pixelY++) { for (int pixelX = element.X1; pixelX <= element.X2; pixelX++) { maxIndex = Math.Max(maxIndex, image.GetPixel(pixelX, pixelY)); } } if (maxIndex < pal.Entries) { var location = image.Arranger.PointToElementLocation(new Point(x + image.Left, y + image.Top)); element = element.WithPalette(pal); image.Arranger.SetElement(element, location.X, location.Y); return(MagitekResult.SuccessResult); } else { return(new MagitekResult.Failed($"Cannot assign the palette '{pal.Name}' because the element contains a palette index ({maxIndex}) outside of the palette")); } } else { return(new MagitekResult.Failed($"Cannot assign the palette '{pal.Name}' because the element is undefined")); } }
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); }