/// <summary> /// Changes mask index to another index. /// </summary> /// <param name="srcBitmap">Source image.</param> /// <param name="replaceWith">Index to substitute for mask index.</param> /// <returns>New DFBitmap with modified mask.</returns> public static DFBitmap ChangeMask(DFBitmap srcBitmap, byte replaceWith = 0) { const int mask = 0xff; // Handle null bitmap or data input if (srcBitmap == null || srcBitmap.Data == null) { return(new DFBitmap()); } // Clone bitmap DFBitmap dstBitmap = DFBitmap.CloneDFBitmap(srcBitmap, false); // Remove all instances of mask index for (int i = 0; i < srcBitmap.Data.Length; i++) { byte index = srcBitmap.Data[i]; if (index == mask) { dstBitmap.Data[i] = replaceWith; } else { dstBitmap.Data[i] = index; } } return(dstBitmap); }
/// <summary> /// Sharpen a DFBitmap. /// </summary> /// <param name="bitmap">Source DFBitmap.</param> /// <param name="passes">Number of sharpen passes.</param> /// <returns>Sharpened DFBitmap.</returns> public static DFBitmap Sharpen(DFBitmap bitmap, int passes = 1) { // Must be a colour format if (bitmap.Format == DFBitmap.Formats.Indexed) { return(null); } DFBitmap newBitmap = DFBitmap.CloneDFBitmap(bitmap); for (int i = 0; i < passes; i++) { // Create horizontal sobel matrix Filter sharpenMatrix = new Filter(3, 3); sharpenMatrix.MyFilter[0, 0] = -1; sharpenMatrix.MyFilter[1, 0] = -1; sharpenMatrix.MyFilter[2, 0] = -1; sharpenMatrix.MyFilter[0, 1] = 1; sharpenMatrix.MyFilter[1, 1] = 12; sharpenMatrix.MyFilter[2, 1] = 1; sharpenMatrix.MyFilter[0, 2] = -1; sharpenMatrix.MyFilter[1, 2] = -1; sharpenMatrix.MyFilter[2, 2] = -1; newBitmap = sharpenMatrix.ApplyFilter(newBitmap); } return(newBitmap); }
/// <summary> /// Dye supported bitmap image based on dye index and type. /// </summary> /// <param name="srcBitmap">Source image.</param> /// <param name="dye">Dye index.</param> /// <param name="target">Dye target.</param> /// <returns>New DFBitmap dyed to specified colour.</returns> public static DFBitmap ChangeDye(DFBitmap srcBitmap, DyeColors dye, DyeTargets target) { const int clothingStart = 0x60; const int weaponsAndArmorStart = 0x70; // Clone bitmap and get colour table for swaps DFBitmap dstBitmap = DFBitmap.CloneDFBitmap(srcBitmap, false); byte[] swaps = GetDyeColorTable(dye, target); // Swaps range is based on target type int start; switch (target) { case DyeTargets.Clothing: start = clothingStart; break; case DyeTargets.WeaponsAndArmor: start = weaponsAndArmorStart; break; default: return(dstBitmap); } // Swap indices start through start + 15 with colour table int rowPos; for (int y = 0; y < srcBitmap.Height; y++) { rowPos = y * srcBitmap.Width; for (int x = 0; x < srcBitmap.Width; x++) { int srcOffset = rowPos + x; byte index = srcBitmap.Data[srcOffset]; if (index >= start && index <= start + 0x0f) { int tintOffset = index - start; dstBitmap.Data[srcOffset] = swaps[tintOffset]; } else { dstBitmap.Data[srcOffset] = index; } } } return(dstBitmap); }
/* * Based on Craig's Utility Library (CUL) by James Craig. * http://www.gutgames.com/post/Edge-detection-in-C.aspx * MIT License (http://www.opensource.org/licenses/mit-license.php) */ /// <summary> /// Gets a new bitmap containing edges detected in source bitmap. /// The source bitmap is unchanged. /// </summary> /// <param name="bitmap">DFBitmap source.</param> /// <param name="threshold">Edge detection threshold.</param> /// <param name="edgeColor">Edge colour to write.</param> /// <returns>DFBitmap containing edges.</returns> private static DFBitmap FindEdges(DFBitmap bitmap, float threshold, DFBitmap.DFColor edgeColor) { // Must be a colour format if (bitmap.Format == DFBitmap.Formats.Indexed) { return(null); } // Clone bitmap settings DFBitmap newBitmap = DFBitmap.CloneDFBitmap(bitmap); for (int x = 0; x < bitmap.Width; x++) { for (int y = 0; y < bitmap.Height; y++) { DFBitmap.DFColor currentColor = DFBitmap.GetPixel(bitmap, x, y); if (y < newBitmap.Height - 1 && x < newBitmap.Width - 1) { DFBitmap.DFColor tempColor = DFBitmap.GetPixel(bitmap, x + 1, y + 1); if (ColorDistance(currentColor, tempColor) > threshold) { DFBitmap.SetPixel(newBitmap, x, y, edgeColor); } } else if (y < newBitmap.Height - 1) { DFBitmap.DFColor tempColor = DFBitmap.GetPixel(bitmap, x, y + 1); if (ColorDistance(currentColor, tempColor) > threshold) { DFBitmap.SetPixel(newBitmap, x, y, edgeColor); } } else if (x < newBitmap.Width - 1) { DFBitmap.DFColor tempColor = DFBitmap.GetPixel(bitmap, x + 1, y); if (ColorDistance(currentColor, tempColor) > threshold) { DFBitmap.SetPixel(newBitmap, x, y, edgeColor); } } } } return(newBitmap); }
/// <summary> /// Applies the filter to the input image /// </summary> /// <param name="Input">input image</param> /// <returns>Returns a separate image with the filter applied</returns> public DFBitmap ApplyFilter(DFBitmap Input) { // Must be a colour format if (Input.Format == DFBitmap.Formats.Indexed) { return(null); } DFBitmap NewBitmap = DFBitmap.CloneDFBitmap(Input); for (int x = 0; x < Input.Width; ++x) { for (int y = 0; y < Input.Height; ++y) { int RValue = 0; int GValue = 0; int BValue = 0; int AValue = 0; int Weight = 0; int XCurrent = -Width / 2; for (int x2 = 0; x2 < Width; ++x2) { if (XCurrent + x < Input.Width && XCurrent + x >= 0) { int YCurrent = -Height / 2; for (int y2 = 0; y2 < Height; ++y2) { if (YCurrent + y < Input.Height && YCurrent + y >= 0) { DFBitmap.DFColor Pixel = DFBitmap.GetPixel(Input, XCurrent + x, YCurrent + y); RValue += MyFilter[x2, y2] * Pixel.r; GValue += MyFilter[x2, y2] * Pixel.g; BValue += MyFilter[x2, y2] * Pixel.b; AValue = Pixel.a; Weight += MyFilter[x2, y2]; } ++YCurrent; } } ++XCurrent; } DFBitmap.DFColor MeanPixel = DFBitmap.GetPixel(Input, x, y); if (Weight == 0) { Weight = 1; } if (Weight > 0) { if (Absolute) { RValue = System.Math.Abs(RValue); GValue = System.Math.Abs(GValue); BValue = System.Math.Abs(BValue); } RValue = (RValue / Weight) + Offset; RValue = Clamp(RValue, 0, 255); GValue = (GValue / Weight) + Offset; GValue = Clamp(GValue, 0, 255); BValue = (BValue / Weight) + Offset; BValue = Clamp(BValue, 0, 255); MeanPixel = DFBitmap.DFColor.FromRGBA((byte)RValue, (byte)GValue, (byte)BValue, (byte)AValue); } DFBitmap.SetPixel(NewBitmap, x, y, MeanPixel); } } return(NewBitmap); }