private static Primitive statistics(string image) { lock (LockingVar) { Type ImageListType = typeof(ImageList); Type GraphicsWindowType = typeof(GraphicsWindow); BitmapSource img; Primitive stats = new Primitive(""); double[] min, max, mean, std; min = new double[3] { 255.0, 255.0, 255.0 }; max = new double[3] { 0.0, 0.0, 0.0 }; mean = new double[3] { 0.0, 0.0, 0.0 }; std = new double[3] { 0.0, 0.0, 0.0 }; try { _savedImages = (Dictionary<string, BitmapSource>)ImageListType.GetField("_savedImages", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null); if (!_savedImages.TryGetValue((string)image, out img)) return stats; Bitmap dImg = FastPixel.GetBitmap(img); FastPixel fp = new FastPixel(dImg); Color c; for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); min[0] = System.Math.Min(min[0], (double)c.R); min[1] = System.Math.Min(min[1], (double)c.G); min[2] = System.Math.Min(min[2], (double)c.B); max[0] = System.Math.Max(max[0], (double)c.R); max[1] = System.Math.Max(max[1], (double)c.G); max[2] = System.Math.Max(max[2], (double)c.B); mean[0] += (double)c.R; mean[1] += (double)c.G; mean[2] += (double)c.B; std[0] += (double)(c.R * c.R); std[1] += (double)(c.G * c.G); std[2] += (double)(c.B * c.B); } } double size = fp.Width * fp.Height; fp.Unlock(false); for (int i = 0; i < 3; i++) { mean[i] /= size; std[i] /= size; std[i] -= mean[i] * mean[i]; std[i] = System.Math.Sqrt(std[i]); stats["Min"] += (i + 1).ToString() + "=" + min[i].ToString(CultureInfo.InvariantCulture) + ";"; stats["Max"] += (i + 1).ToString() + "=" + max[i].ToString(CultureInfo.InvariantCulture) + ";"; stats["Mean"] += (i + 1).ToString() + "=" + mean[i].ToString(CultureInfo.InvariantCulture) + ";"; stats["STD"] += (i + 1).ToString() + "=" + std[i].ToString(CultureInfo.InvariantCulture) + ";"; } stats["Min"] = Utilities.CreateArrayMap(stats["Min"]); stats["Max"] = Utilities.CreateArrayMap(stats["Max"]); stats["Mean"] = Utilities.CreateArrayMap(stats["Mean"]); stats["STD"] = Utilities.CreateArrayMap(stats["STD"]); } catch (Exception ex) { Utilities.OnError(Utilities.GetCurrentMethod(), ex); } return stats; } }
/// <summary> /// Replace one colour in an ImageList image with another. /// </summary> /// <param name="image">The ImageList image.</param> /// <param name="colourFrom">The colour to replace.</param> /// <param name="colourTo">The replacement colour to apply.</param> /// <param name="tolerance">A tolerance for the colour to match (default 0 - exact match). /// ARGB pixel values all within the tolerance will be replaced.</param> public static void ReplaceColour(Primitive image, Primitive colourFrom, Primitive colourTo, Primitive tolerance) { lock (LockingVar) { Type ImageListType = typeof(ImageList); Type GraphicsWindowType = typeof(GraphicsWindow); BitmapSource img; try { _savedImages = (Dictionary<string, BitmapSource>)ImageListType.GetField("_savedImages", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null); if (!_savedImages.TryGetValue((string)image, out img)) return; Bitmap dImg = FastPixel.GetBitmap(img); FastPixel fp = new FastPixel(dImg); Color cFrom = (Color)colConvert.ConvertFromString(colourFrom); Color cTo = (Color)colConvert.ConvertFromString(colourTo); if (tolerance == "") tolerance = 0; for (int x = 0; x < fp.Width; x++) { for (int y = 0; y < fp.Height; y++) { Color c = fp.GetPixel(x, y); if (System.Math.Abs(c.A - cFrom.A) > tolerance) continue; if (System.Math.Abs(c.R - cFrom.R) > tolerance) continue; if (System.Math.Abs(c.G - cFrom.G) > tolerance) continue; if (System.Math.Abs(c.B - cFrom.B) > tolerance) continue; fp.SetPixel(x, y, cTo); } } fp.Unlock(true); FastThread.SaveBitmap(image, dImg); } catch (Exception ex) { Utilities.OnError(Utilities.GetCurrentMethod(), ex); } } }
private static Primitive histogram(string image) { lock (LockingVar) { Type ImageListType = typeof(ImageList); Type GraphicsWindowType = typeof(GraphicsWindow); BitmapSource img; Primitive stats = new Primitive(""); int[] red, green, blue; red = new int[256]; green = new int[256]; blue = new int[256]; for (int i = 0; i < 256; i++) { red[i] = 0; green[i] = 0; blue[i] = 0; } try { _savedImages = (Dictionary<string, BitmapSource>)ImageListType.GetField("_savedImages", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null); if (!_savedImages.TryGetValue((string)image, out img)) return stats; Bitmap dImg = FastPixel.GetBitmap(img); FastPixel fp = new FastPixel(dImg); Color c; for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); red[c.R]++; green[c.G]++; blue[c.B]++; } } fp.Unlock(false); for (int i = 0; i < 256; i++) { stats[1] += i.ToString() + "=" + red[i].ToString() + ";"; stats[2] += i.ToString() + "=" + green[i].ToString() + ";"; stats[3] += i.ToString() + "=" + blue[i].ToString() + ";"; } stats[1] = Utilities.CreateArrayMap(stats[1]); stats[2] = Utilities.CreateArrayMap(stats[2]); stats[3] = Utilities.CreateArrayMap(stats[3]); } catch (Exception ex) { Utilities.OnError(Utilities.GetCurrentMethod(), ex); } return stats; } }
/// <summary> /// Cartoon effect received by combining oil paint algorithm and Sobel edge detecting /// </summary> /// <param name="OriginalImage">Original ARGB image</param> /// <param name="R">Radius of oil paint algorithm</param> /// <param name="Level">Available levels of intensity</param> /// <param name="InverseThreshold">Inverse threshold</param> /// <returns>Cartoon effect result</returns> public Bitmap Cartoon(Bitmap OriginalImage, int R, int Level, int InverseThreshold) { Bitmap image = OriginalImage; Bitmap image2 = new Bitmap(image.Width, image.Height); Bitmap oilpaint = this.OilPaint(image, R, Level); Bitmap edge = this.ToBlackwhiteInverse(this.ImageSobelFilterGS(image), InverseThreshold); FastPixel fpOilpaint = new FastPixel(oilpaint); FastPixel fpEdge = new FastPixel(edge); FastPixel fpImage2 = new FastPixel(image2); for (int i = 0; i < fpImage2.Width; i++) { for (int j = 0; j < fpImage2.Height; j++) { if (fpEdge.GetPixel(i, j).R == 255) { fpImage2.SetPixel(i, j, fpOilpaint.GetPixel(i, j)); } else { fpImage2.SetPixel(i, j, fpEdge.GetPixel(i, j)); } } } fpOilpaint.Unlock(false); fpEdge.Unlock(false); fpImage2.Unlock(true); return image2; }
/// <summary> /// Multiply colour values of image. /// An image has pixels with R,G,B in the range 0 to 255. /// </summary> /// <param name="image">The ImageList image to modify.</param> /// <param name="red">Red value to multiply by.</param> /// <param name="green">Geen value to multiply by.</param> /// <param name="blue">Blue value to multiply by.</param> public static void Multiply(Primitive image, Primitive red, Primitive green, Primitive blue) { lock (LockingVar) { Type ImageListType = typeof(ImageList); Type GraphicsWindowType = typeof(GraphicsWindow); BitmapSource img; try { _savedImages = (Dictionary<string, BitmapSource>)ImageListType.GetField("_savedImages", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null); if (!_savedImages.TryGetValue((string)image, out img)) return; Bitmap dImg = FastPixel.GetBitmap(img); Color c; FastPixel fp = new FastPixel(dImg); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); fp.SetPixel(i, j, Color.FromArgb(c.A, range(c.R * red), range(c.G * green), range(c.B * blue))); } } fp.Unlock(true); FastThread.SaveBitmap(image, dImg); } catch (Exception ex) { Utilities.OnError(Utilities.GetCurrentMethod(), ex); } } }
/// <summary> /// Difference 2 images. /// An image has pixels with R,G,B in the range 0 to 255. /// Both images must be the same dimension. /// </summary> /// <param name="image1">The first ImageList image to difference.</param> /// <param name="image2">The second ImageList image to difference.</param> /// <returns>A new ImageList image with the result or "" on failure.</returns> public static Primitive DifferenceImages(Primitive image1, Primitive image2) { lock (LockingVar) { Type ImageListType = typeof(ImageList); Type GraphicsWindowType = typeof(GraphicsWindow); Type ShapesType = typeof(Shapes); BitmapSource img1, img2; string imageNew = ""; try { _savedImages = (Dictionary<string, BitmapSource>)ImageListType.GetField("_savedImages", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null); if (!_savedImages.TryGetValue((string)image1, out img1)) return imageNew; if (!_savedImages.TryGetValue((string)image2, out img2)) return imageNew; MethodInfo method = ShapesType.GetMethod("GenerateNewName", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase); imageNew = method.Invoke(null, new object[] { "ImageList" }).ToString(); Bitmap dImg1 = FastPixel.GetBitmap(img1); Bitmap dImg2 = FastPixel.GetBitmap(img2); if (dImg1.Width == dImg2.Width && dImg1.Height == dImg2.Height) { Color c1, c2; FastPixel fpImg1 = new FastPixel(dImg1); FastPixel fpImg2 = new FastPixel(dImg2); for (int i = 0; i < fpImg1.Width; i++) { for (int j = 0; j < fpImg1.Height; j++) { c1 = fpImg1.GetPixel(i, j); c2 = fpImg2.GetPixel(i, j); fpImg1.SetPixel(i, j, Color.FromArgb(range(System.Math.Abs(c1.R - c2.R)), range(System.Math.Abs(c1.G - c2.G)), range(System.Math.Abs(c1.B - c2.B)))); } } fpImg1.Unlock(true); fpImg2.Unlock(false); FastThread.SaveBitmap(imageNew, dImg1, true); } } catch (Exception ex) { Utilities.OnError(Utilities.GetCurrentMethod(), ex); } return imageNew; } }
/// <summary> /// Fill a region surrounding a specified pixel. /// All neighbour pixels of the same colour are changed. /// This only applies to the drawing layer of the GraphicsWindow. /// </summary> /// <param name="x"> /// The x co-ordinate of the pixel to start the fill. /// </param> /// <param name="y"> /// The y co-ordinate of the pixel to start the fill. /// </param> /// <param name="colour"> /// The colour to fill with. /// </param> public static void FloodFill(Primitive x, Primitive y, Primitive colour) { Type GraphicsWindowType = typeof(GraphicsWindow); x = (int)x; y = (int)y; try { InvokeHelper ret = new InvokeHelper(delegate { try { //Prepare bitmap GraphicsWindowType.GetMethod("Rasterize", BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { }); RenderTargetBitmap _renderBitmap = (RenderTargetBitmap)GraphicsWindowType.GetField("_renderBitmap", BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); FastPixel fp = new FastPixel(_renderBitmap); System.Drawing.Color colNew = ColorTranslator.FromHtml(colour); System.Drawing.Color colOld = fp.GetPixel(x, y); if (colNew == colOld) return; int nx = fp.Width; int ny = fp.Height; Stack<int> points = new Stack<int>(); int point, _x, _y; points.Push(y * nx + x); while (points.Count > 0) { point = points.Pop(); _x = point % nx; _y = point / nx; fp.SetPixel(_x, _y, colNew); if (_x > 0 && colOld == fp.GetPixel(_x - 1, _y)) points.Push(_y * nx + _x - 1); if (_x < nx - 1 && colOld == fp.GetPixel(_x + 1, _y)) points.Push(_y * nx + _x + 1); if (_y > 0 && colOld == fp.GetPixel(_x, _y - 1)) points.Push((_y - 1) * nx + _x); if (_y < ny - 1 && colOld == fp.GetPixel(_x, _y + 1)) points.Push((_y + 1) * nx + _x); } fp.Unlock(true); //Display bitmap BitmapImage bitmapImage = fp.BitmapImage; DrawingGroup _mainDrawing = (DrawingGroup)GraphicsWindowType.GetField("_mainDrawing", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null); DrawingContext drawingContext = _mainDrawing.Append(); drawingContext.DrawImage(bitmapImage, new Rect(0, 0, nx, ny)); drawingContext.Close(); _renderBitmap.Clear(); GraphicsWindowType.GetMethod("AddRasterizeOperationToQueue", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).Invoke(null, new object[] { }); } catch (Exception ex) { Utilities.OnError(Utilities.GetCurrentMethod(), ex); } }); FastThread.Invoke(ret); } catch (Exception ex) { Utilities.OnError(Utilities.GetCurrentMethod(), ex); } }
/// <summary> /// Color accent filtration /// </summary> /// <param name="OriginalImage">Original ARGB image</param> /// <param name="h">Hue of accented color</param> /// <param name="range">Range of acceptance</param> /// <returns>Color accent filtration</returns> public Bitmap ColorAccent(Bitmap OriginalImage, Double h, Double range) { FastPixel fpOriginal = new FastPixel(OriginalImage); Bitmap OutputImage = new System.Drawing.Bitmap(fpOriginal.Width, fpOriginal.Height); FastPixel fpOutput = new FastPixel(OutputImage); Double h1 = (h - range / 2 + 360) % 360; Double h2 = (h + range / 2 + 360) % 360; for (int x = 0; x < fpOriginal.Width; x++) { for (int y = 0; y < fpOriginal.Height; y++) { Color pixel = fpOriginal.GetPixel(x, y); Double[] hsv = this.rgb2hsv(pixel); int red = 0, green = 0, blue = 0; //if (hsv[0] if (h1 <= h2) { if (hsv[0] <= h2 && hsv[0] >= h1) { red = pixel.R; green = pixel.G; blue = pixel.B; } else { int gs = (int)((pixel.R * 0.3) + (pixel.G * 0.59) + (pixel.B * 0.11)); red = gs; green = gs; blue = gs; } } else { if (hsv[0] <= h2 || hsv[0] >= h1) { red = pixel.R; green = pixel.G; blue = pixel.B; } else { int gs = (int)((pixel.R * 0.3) + (pixel.G * 0.59) + (pixel.B * 0.11)); red = gs; green = gs; blue = gs; } } if (red > 255) red = 255; if (red < 0) red = 0; if (green > 255) green = 255; if (green < 0) green = 0; if (blue > 255) blue = 255; if (blue < 0) blue = 0; Color newColor = Color.FromArgb(255, red, green, blue); ; fpOutput.SetPixel(x, y, newColor); } } fpOriginal.Unlock(false); fpOutput.Unlock(true); return OutputImage; }
/// <summary> /// Oil paint filtration /// </summary> /// <param name="OriginalImage">original ARGB image</param> /// <param name="R">Radius of oil paint algorithm</param> /// <param name="Level">Available levels of intensity</param> /// <returns>Oil paint filtred image</returns> public Bitmap OilPaint(Bitmap OriginalImage, int R, int Level) { Bitmap image = OriginalImage; FastPixel fpImage = new FastPixel(image); Bitmap image2 = new Bitmap(fpImage.Width, fpImage.Height); FastPixel fpImage2 = new FastPixel(image2); if (Level < 1 || Level > 255) { throw new Exception("Available intensity levels must be between 1 and 255"); } if (R % 2 == 0) { throw new Exception("Filter mask dimension must be odd."); } if (R < 3) { throw new Exception("Filter mask dimension must be greater or equal 3."); } int range = (int)Math.Floor(Convert.ToDouble(R / 2)); for (int m = range; m < fpImage.Width - range; m++) { for (int n = range; n < fpImage.Height - range; n++) { Double[,,] roi = new Double[3, R, R]; int tmpi = 0; int tmpj = 0; int newValueR = 0; int newValueG = 0; int newValueB = 0; for (int i = m - range; i < m + range + 1; i++) { for (int j = n - range; j < n + range + 1; j++) { Color pixel = fpImage.GetPixel(i, j); Double pR = Convert.ToDouble(pixel.R); Double pG = Convert.ToDouble(pixel.G); Double pB = Convert.ToDouble(pixel.B); roi[0, tmpi, tmpj] = (int)pR; roi[1, tmpi, tmpj] = (int)pG; roi[2, tmpi, tmpj] = (int)pB; tmpj++; } tmpi++; tmpj = 0; } int[] avgR = new int[256]; int[] avgG = new int[256]; int[] avgB = new int[256]; int[] intCnt = new int[256]; for (int k = 0; k < R; k++) { for (int l = 0; l < R; l++) { int intensity = (int)(((roi[0, k, l] + roi[1, k, l] + roi[2, k, l]) / 3) * Convert.ToDouble(Level) / 255); intCnt[intensity]++; avgR[intensity] += (int)roi[0, k, l]; avgG[intensity] += (int)roi[1, k, l]; avgB[intensity] += (int)roi[2, k, l]; } } int maxCur = 0; int maxIndex = 0; for (int a = 0; a < 256; a++) { if (intCnt[a] > maxCur) { maxCur = intCnt[a]; maxIndex = a; } } newValueR = avgR[maxIndex] / maxCur; newValueG = avgG[maxIndex] / maxCur; newValueB = avgB[maxIndex] / maxCur; if (newValueR > 255) newValueR = 255; if (newValueR < 0) newValueR = 0; if (newValueG > 255) newValueG = 255; if (newValueG < 0) newValueG = 0; if (newValueB > 255) newValueB = 255; if (newValueB < 0) newValueB = 0; fpImage2.SetPixel(m, n, Color.FromArgb(255, newValueR, newValueG, newValueB)); } } fpImage.Unlock(false); fpImage2.Unlock(true); return image2; }
/// <summary> /// Converts ARGB images to greyscale using luminance method and calculates image filtartion with SD-ROM mask of size 3. /// </summary> /// <param name="OriginalImage">Orignal ARGB image</param> /// <returns>Filtred image</returns> public Bitmap ImageSDROMFilterGS(Bitmap OriginalImage) { Bitmap image = OriginalImage; FastPixel fpImage = new FastPixel(image); Bitmap image2 = new Bitmap(fpImage.Width, fpImage.Height); FastPixel fpImage2 = new FastPixel(image2); int[] thresholds = new int[4] { 20, 40, 60, 80 }; int size = 3; int range = (int)Math.Floor(Convert.ToDouble(size / 2)); for (int m = range; m < fpImage.Width - range; m++) { for (int n = range; n < fpImage.Height - range; n++) { int[,] roi = new int[size, size]; int tmpj = 0; int tmpi = 0; int newValue = 0; Color CPixel = fpImage.GetPixel(m, n); int CP = (int)Convert.ToDouble((CPixel.R * 0.3) + (CPixel.G * 0.59) + (CPixel.B * 0.11)); for (int i = m - range; i < m + range + 1; i++) { for (int j = n - range; j < n + range + 1; j++) { Color pixel = fpImage.GetPixel(i, j); Double p = Convert.ToDouble((pixel.R * 0.3) + (pixel.G * 0.59) + (pixel.B * 0.11)); roi[tmpi, tmpj] = (int)p; tmpj++; } tmpi++; tmpj = 0; } int[] roivector = new int[size * size - 1]; int tmp = 0; for (int i = 0; i < roi.GetLength(0); i++) { for (int j = 0; j < roi.GetLength(1); j++) { if (i == range && j == range) { } else { roivector[tmp] = roi[i, j]; tmp++; } } } System.Array.Sort(roivector); int ROM = 0; int sizeROI = roivector.Length; int mid = sizeROI / 2 - 1; Double a = Convert.ToDouble(roivector[mid]); Double b = Convert.ToDouble(roivector[mid + 1]); Double c = (a + b) / 2; ROM = (int)c; int[] ROD = new int[mid + 1]; for (int i = 0; i < mid; i++) { if (CP <= ROM) { ROD[i] = roivector[i] - CP; } else { ROD[i] = CP - roivector[roivector.GetLength(0) - 1 - i]; } } newValue = CP; for (int i = 0; i < mid; i++) { if (ROD[i] > thresholds[i]) { newValue = ROM; break; } } if (newValue > 255) newValue = 255; if (newValue < 0) newValue = 0; fpImage2.SetPixel(m, n, Color.FromArgb(255, newValue, newValue, newValue)); } } fpImage.Unlock(false); fpImage2.Unlock(true); return image2; }
/// <summary> /// Converts ARGB images to greyscale using luminance method and calculates module of image convolution with Sobel operators (horizontal and vertical axis) /// </summary> /// <param name="OriginalImage">Original ARGB image</param> /// <returns>Filtered image</returns> public Bitmap ImageSobelFilterGS(Bitmap OriginalImage) { Bitmap image = OriginalImage; FastPixel fpImage = new FastPixel(image); Bitmap image2 = new Bitmap(fpImage.Width, fpImage.Height); FastPixel fpImage2 = new FastPixel(image2); for (int m = 1; m < fpImage.Width - 1; m++) { for (int n = 1; n < fpImage.Height - 1; n++) { Color pixel1 = fpImage.GetPixel(m - 1, n - 1); Color pixel2 = fpImage.GetPixel(m, n - 1); Color pixel3 = fpImage.GetPixel(m + 1, n - 1); Color pixel4 = fpImage.GetPixel(m - 1, n); Color pixel5 = fpImage.GetPixel(m, n); Color pixel6 = fpImage.GetPixel(m + 1, n); Color pixel7 = fpImage.GetPixel(m - 1, n + 1); Color pixel8 = fpImage.GetPixel(m, n + 1); Color pixel9 = fpImage.GetPixel(m + 1, n + 1); Double p1 = Convert.ToDouble((pixel1.R * 0.3) + (pixel1.G * 0.59) + (pixel1.B * 0.11)); Double p2 = Convert.ToDouble((pixel2.R * 0.3) + (pixel2.G * 0.59) + (pixel2.B * 0.11)); Double p3 = Convert.ToDouble((pixel3.R * 0.3) + (pixel3.G * 0.59) + (pixel3.B * 0.11)); Double p4 = Convert.ToDouble((pixel4.R * 0.3) + (pixel4.G * 0.59) + (pixel4.B * 0.11)); Double p5 = Convert.ToDouble((pixel5.R * 0.3) + (pixel5.G * 0.59) + (pixel5.B * 0.11)); Double p6 = Convert.ToDouble((pixel6.R * 0.3) + (pixel6.G * 0.59) + (pixel6.B * 0.11)); Double p7 = Convert.ToDouble((pixel7.R * 0.3) + (pixel7.G * 0.59) + (pixel7.B * 0.11)); Double p8 = Convert.ToDouble((pixel8.R * 0.3) + (pixel8.G * 0.59) + (pixel8.B * 0.11)); Double p9 = Convert.ToDouble((pixel9.R * 0.3) + (pixel9.G * 0.59) + (pixel9.B * 0.11)); int x = (int)((p1 + (p2 + p2) + p3 - p7 - (p8 + p8) - p9)); int y = (int)((p3 + (p6 + p6) + p9 - p1 - (p4 + p4) - p7)); int newgs = (int)(Math.Abs(x) + Math.Abs(y)); if (newgs > 255) newgs = 255; if (newgs < 0) newgs = 0; fpImage2.SetPixel(m, n, Color.FromArgb(255, newgs, newgs, newgs)); } } fpImage.Unlock(false); fpImage2.Unlock(true); return image2; }
/// <summary> /// Ccalculates image filtartion with SD-ROM mask of size 3. /// </summary> /// <param name="OriginalImage">Orignal ARGB image</param> /// <returns>Filtred image</returns> public Bitmap ImageSDROMFilterColor(Bitmap OriginalImage) { Bitmap image = OriginalImage; FastPixel fpImage = new FastPixel(image); Bitmap image2 = new Bitmap(fpImage.Width, fpImage.Height); FastPixel fpImage2 = new FastPixel(image2); int[] thresholds = new int[4] { 20, 40, 60, 80 }; int size = 3; int range = (int)Math.Floor(Convert.ToDouble(size / 2)); for (int m = range; m < fpImage.Width - range; m++) { for (int n = range; n < fpImage.Height - range; n++) { int[,] roiR = new int[size, size]; int[,] roiG = new int[size, size]; int[,] roiB = new int[size, size]; int tmpj = 0; int tmpi = 0; int newValueR = 0; int newValueG = 0; int newValueB = 0; Color CPixel = fpImage.GetPixel(m, n); int CPR = (int)(CPixel.R); int CPG = (int)(CPixel.G); int CPB = (int)(CPixel.B); for (int i = m - range; i < m + range + 1; i++) { for (int j = n - range; j < n + range + 1; j++) { Color pixel = fpImage.GetPixel(i, j); Double pR = Convert.ToDouble(pixel.R); Double pG = Convert.ToDouble(pixel.G); Double pB = Convert.ToDouble(pixel.B); roiR[tmpi, tmpj] = (int)pR; roiG[tmpi, tmpj] = (int)pG; roiB[tmpi, tmpj] = (int)pB; tmpj++; } tmpi++; tmpj = 0; } int[] roivectorR = new int[size * size - 1]; int[] roivectorG = new int[size * size - 1]; int[] roivectorB = new int[size * size - 1]; int tmp = 0; for (int i = 0; i < roiR.GetLength(0); i++) { for (int j = 0; j < roiR.GetLength(1); j++) { if (i == range && j == range) { } else { roivectorR[tmp] = roiR[i, j]; roivectorG[tmp] = roiG[i, j]; roivectorB[tmp] = roiB[i, j]; tmp++; } } } System.Array.Sort(roivectorR); System.Array.Sort(roivectorG); System.Array.Sort(roivectorB); int ROMR = 0; int ROMG = 0; int ROMB = 0; int sizeROI = roivectorR.Length; int mid = sizeROI / 2 - 1; Double a = Convert.ToDouble(roivectorR[mid]); Double b = Convert.ToDouble(roivectorR[mid + 1]); Double c = (a + b) / 2; ROMR = (int)c; a = Convert.ToDouble(roivectorG[mid]); b = Convert.ToDouble(roivectorG[mid + 1]); c = (a + b) / 2; ROMG = (int)c; a = Convert.ToDouble(roivectorB[mid]); b = Convert.ToDouble(roivectorB[mid + 1]); c = (a + b) / 2; ROMB = (int)c; int[] RODR = new int[mid + 1]; int[] RODG = new int[mid + 1]; int[] RODB = new int[mid + 1]; for (int i = 0; i < mid; i++) { if (CPR <= ROMR) { RODR[i] = roivectorR[i] - CPR; } else { RODR[i] = CPR - roivectorR[roivectorR.GetLength(0) - 1 - i]; } if (CPG <= ROMG) { RODG[i] = roivectorG[i] - CPG; } else { RODG[i] = CPG - roivectorG[roivectorG.GetLength(0) - 1 - i]; } if (CPB <= ROMB) { RODB[i] = roivectorB[i] - CPB; } else { RODB[i] = CPB - roivectorB[roivectorB.GetLength(0) - 1 - i]; } } newValueR = CPR; for (int i = 0; i < mid; i++) { if (RODR[i] > thresholds[i]) { newValueR = ROMR; break; } } if (newValueR > 255) newValueR = 255; if (newValueR < 0) newValueR = 0; newValueG = CPG; for (int i = 0; i < mid; i++) { if (RODG[i] > thresholds[i]) { newValueG = ROMG; break; } } if (newValueG > 255) newValueG = 255; if (newValueG < 0) newValueG = 0; newValueB = CPB; for (int i = 0; i < mid; i++) { if (RODB[i] > thresholds[i]) { newValueB = ROMB; break; } } if (newValueB > 255) newValueB = 255; if (newValueB < 0) newValueB = 0; fpImage2.SetPixel(m, n, Color.FromArgb(255, newValueR, newValueG, newValueB)); } } fpImage.Unlock(false); fpImage2.Unlock(true); return image2; }
/// <summary> /// Calculates module of image convolution with Prewitt operators (horizontal and vertical axis) /// </summary> /// <param name="OriginalImage">Original ARGB image</param> /// <returns>Filtered image</returns> public Bitmap ImagePrewittFilterColor(Bitmap OriginalImage) { Bitmap image = OriginalImage; FastPixel fpImage = new FastPixel(image); Bitmap image2 = new Bitmap(fpImage.Width, fpImage.Height); FastPixel fpImage2 = new FastPixel(image2); for (int m = 1; m < fpImage.Width - 1; m++) { for (int n = 1; n < fpImage.Height - 1; n++) { Color pixel1 = fpImage.GetPixel(m - 1, n - 1); Color pixel2 = fpImage.GetPixel(m, n - 1); Color pixel3 = fpImage.GetPixel(m + 1, n - 1); Color pixel4 = fpImage.GetPixel(m - 1, n); Color pixel5 = fpImage.GetPixel(m, n); Color pixel6 = fpImage.GetPixel(m + 1, n); Color pixel7 = fpImage.GetPixel(m - 1, n + 1); Color pixel8 = fpImage.GetPixel(m, n + 1); Color pixel9 = fpImage.GetPixel(m + 1, n + 1); Double p1r = Convert.ToDouble(pixel1.R); Double p2r = Convert.ToDouble(pixel2.R); Double p3r = Convert.ToDouble(pixel3.R); Double p4r = Convert.ToDouble(pixel4.R); Double p5r = Convert.ToDouble(pixel5.R); Double p6r = Convert.ToDouble(pixel6.R); Double p7r = Convert.ToDouble(pixel7.R); Double p8r = Convert.ToDouble(pixel8.R); Double p9r = Convert.ToDouble(pixel9.R); Double p1g = Convert.ToDouble(pixel1.G); Double p2g = Convert.ToDouble(pixel2.G); Double p3g = Convert.ToDouble(pixel3.G); Double p4g = Convert.ToDouble(pixel4.G); Double p5g = Convert.ToDouble(pixel5.G); Double p6g = Convert.ToDouble(pixel6.G); Double p7g = Convert.ToDouble(pixel7.G); Double p8g = Convert.ToDouble(pixel8.G); Double p9g = Convert.ToDouble(pixel9.G); Double p1b = Convert.ToDouble(pixel1.B); Double p2b = Convert.ToDouble(pixel2.B); Double p3b = Convert.ToDouble(pixel3.B); Double p4b = Convert.ToDouble(pixel4.B); Double p5b = Convert.ToDouble(pixel5.B); Double p6b = Convert.ToDouble(pixel6.B); Double p7b = Convert.ToDouble(pixel7.B); Double p8b = Convert.ToDouble(pixel8.B); Double p9b = Convert.ToDouble(pixel9.B); int xr = (int)(p1r + p2r + p3r - p7r - p8r - p9r); int yr = (int)(p1r - p3r + p4r - p6r + p7r - p9r); int newgsr = (int)(Math.Abs(xr) + Math.Abs(yr)); if (newgsr > 255) newgsr = 255; if (newgsr < 0) newgsr = 0; int xg = (int)(p1g + p2g + p3g - p7g - p8g - p9g); int yg = (int)(p1g - p3g + p4g - p6g + p7g - p9g); int newgsg = (int)(Math.Abs(xg) + Math.Abs(yg)); if (newgsg > 255) newgsg = 255; if (newgsg < 0) newgsg = 0; int xb = (int)(p1b + p2b + p3b - p7b - p8b - p9b); int yb = (int)(p1b - p3b + p4b - p6b + p7b - p9b); int newgsb = (int)(Math.Abs(xb) + Math.Abs(yb)); if (newgsb > 255) newgsb = 255; if (newgsb < 0) newgsb = 0; fpImage2.SetPixel(m, n, Color.FromArgb(255, newgsr, newgsg, newgsb)); } } fpImage.Unlock(false); fpImage2.Unlock(true); return image2; }
/// <summary> /// Converts ARGB images to greyscale using luminance method and calculates image filtartion with median mask of given size. /// </summary> /// <param name="OriginalImage">Orignal ARGB image</param> /// <param name="size">Median mask dimension</param> /// <returns>Filtered image</returns> public Bitmap ImageMedianFilterGS(Bitmap OriginalImage, int size) { Bitmap image = OriginalImage; FastPixel fpImage = new FastPixel(OriginalImage); Bitmap image2 = new Bitmap(fpImage.Width, fpImage.Height); FastPixel fpImage2 = new FastPixel(image2); if (size % 2 == 0) { throw new Exception("Median filter dimension must be odd."); } if (size < 3) { throw new Exception("Filter mask dimension must be greater or equal 3."); } int range = (int)Math.Floor(Convert.ToDouble(size / 2)); for (int m = range; m < fpImage.Width - range; m++) { for (int n = range; n < fpImage.Height - range; n++) { int[] roi = new int[size * size]; int tmp = 0; int newValue = 0; for (int i = m - range; i < m + range + 1; i++) { for (int j = n - range; j < n + range + 1; j++) { Color pixel = fpImage.GetPixel(i, j); Double p = Convert.ToDouble((pixel.R * 0.3) + (pixel.G * 0.59) + (pixel.B * 0.11)); roi[tmp] = (int)p; tmp++; } } System.Array.Sort(roi); decimal Median = 0; int sizeROI = roi.Length; int mid = sizeROI / 2; Median = (sizeROI % 2 != 0) ? (decimal)roi[mid] : ((decimal)roi[mid] + (decimal)roi[mid + 1]) / 2; newValue = (int)Median; if (newValue > 255) newValue = 255; if (newValue < 0) newValue = 0; fpImage2.SetPixel(m, n, Color.FromArgb(255, newValue, newValue, newValue)); } } fpImage.Unlock(false); fpImage2.Unlock(true); return image2; }
private void Shadow_Delegate() { try { Bitmap bm = FastPixel.GetBitmap((BitmapSource)image.Source); FastPixel fp = new FastPixel(bm); width = fp.Width; height = fp.Height; vectors = new Vec3D[width, height]; Color c; for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { c = fp.GetPixel(i, j); vectors[i, j] = new Vec3D(c.R - 128f, c.G - 128f, c.B - 128f); vectors[i, j].Normalize(); } } fp.Unlock(false); } catch (Exception ex) { Utilities.OnError(Utilities.GetCurrentMethod(), ex); } }
/// <summary> /// Sepia filtration /// </summary> /// <param name="OriginalImage">Original ARGB image</param> /// <param name="Coef">Sepia level</param> /// <returns>Sepia image</returns> public Bitmap Sepia(Bitmap OriginalImage, Double Coef) { FastPixel fpOriginal = new FastPixel(OriginalImage); Bitmap OutputImage = new System.Drawing.Bitmap(fpOriginal.Width, fpOriginal.Height); FastPixel fpOutput = new FastPixel(OutputImage); for (int x = 0; x < fpOriginal.Width; x++) { for (int y = 0; y < fpOriginal.Height; y++) { Color pixel = fpOriginal.GetPixel(x, y); int gs = (int)((pixel.R * 0.3) + (pixel.G * 0.59) + (pixel.B * 0.11)); int red = (int)(gs + 2 * Coef); int green = (int)(gs + Coef); int blue = (int)(gs); if (red > 255) red = 255; if (red < 0) red = 0; if (green > 255) green = 255; if (green < 0) green = 0; if (blue > 255) blue = 255; if (blue < 0) blue = 0; Color newColor = Color.FromArgb(255, red, green, blue); ; fpOutput.SetPixel(x, y, newColor); } } fpOriginal.Unlock(false); fpOutput.Unlock(true); return OutputImage; }
/// <summary> /// Performs a colour matrix transformation on an image. /// This can be used for all sorts of colour transformations. /// See http://msdn.microsoft.com/en-us/library/a7xw19wh%28v=vs.110%29.aspx. /// </summary> /// <param name="image">The ImageList image to modify.</param> /// <param name="matrix">A 5*5 2D matrix. /// Sepia Example: /// matrix[1] = "1=0.393;2=0.349;3=0.272;4=0;5=0" /// matrix[2] = "1=0.769;2=0.686;3=0.534;4=0;5=0" /// matrix[3] = "1=0.189;2=0.168;3=0.131;4=0;5=0" /// matrix[4] = "1=0;2=0;3=0;4=1;5=0" /// matrix[5] = "1=0;2=0;3=0;4=0;5=1" /// </param> public static void ColorMatrix(Primitive image, Primitive matrix) { lock (LockingVar) { Type ImageListType = typeof(ImageList); Type GraphicsWindowType = typeof(GraphicsWindow); BitmapSource img; try { _savedImages = (Dictionary<string, BitmapSource>)ImageListType.GetField("_savedImages", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null); if (!_savedImages.TryGetValue((string)image, out img)) return; double[,] data = new double[5, 5]; Primitive rows = SBArray.GetAllIndices(matrix); if (SBArray.GetItemCount(rows) != 5) { Utilities.OnError(Utilities.GetCurrentMethod(), new Exception("Incorrectly dimensioned matrix")); return; } for (int i = 1; i <= 5; i++) { Primitive cols = SBArray.GetAllIndices(rows); if (SBArray.GetItemCount(cols) != 5) { Utilities.OnError(Utilities.GetCurrentMethod(), new Exception("Incorrectly dimensioned matrix")); return; } for (int j = 1; j <= 5; j++) { data[i - 1, j - 1] = matrix[rows[i]][cols[j]]; } } Bitmap dImg = FastPixel.GetBitmap(img); Color c; byte A, R, G, B; FastPixel fp = new FastPixel(dImg); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); R = range(c.R * data[0, 0] + c.G * data[1, 0] + c.B * data[2, 0] + c.A * data[3, 0] + 255 * data[4, 0] * data[4, 4]); G = range(c.R * data[0, 1] + c.G * data[1, 1] + c.B * data[2, 1] + c.A * data[3, 1] + 255 * data[4, 1] * data[4, 4]); B = range(c.R * data[0, 2] + c.G * data[1, 2] + c.B * data[2, 2] + c.A * data[3, 2] + 255 * data[4, 2] * data[4, 4]); A = range(c.R * data[0, 3] + c.G * data[1, 3] + c.B * data[2, 3] + c.A * data[3, 3] + 255 * data[4, 3] * data[4, 4]); fp.SetPixel(i, j, Color.FromArgb(A, R, G, B)); } } fp.Unlock(true); FastThread.SaveBitmap(image, dImg); } catch (Exception ex) { Utilities.OnError(Utilities.GetCurrentMethod(), ex); } } }
/// <summary> /// Converts ARGB image to black and white and inverses it with respect to given threshold /// </summary> /// <param name="OriginalImage">Original ARGB image</param> /// <param name="threshold">Threshold</param> /// <returns>Balck and white image</returns> public Bitmap ToBlackwhiteInverse(Bitmap OriginalImage, int threshold) { FastPixel fpOriginal = new FastPixel(OriginalImage); Bitmap OutputImage = new System.Drawing.Bitmap(fpOriginal.Width, fpOriginal.Height); FastPixel fpOutput = new FastPixel(OutputImage); if (threshold < 1 || threshold > 254) { throw new Exception("Threshold value must be in range from 1 to 254"); } for (int x = 0; x < fpOriginal.Width; x++) { for (int y = 0; y < fpOriginal.Height; y++) { Color pixel = fpOriginal.GetPixel(x, y); int gs = (int)((pixel.R * 0.3) + (pixel.G * 0.59) + (pixel.B * 0.11)); if (gs > threshold) gs = 0; else gs = 255; Color newColor = Color.FromArgb(255, gs, gs, gs); fpOutput.SetPixel(x, y, newColor); } } fpOriginal.Unlock(false); fpOutput.Unlock(true); return OutputImage; }
/// <summary> /// Get a 2D array filled with all the pixels in an image. /// </summary> /// <param name="image">The ImageList image.</param> /// <returns>An array of hex based image pixel colours indexed by [x][y].</returns> public static Primitive GetImagePixels(Primitive image) { lock (LockingVar) { Type ImageListType = typeof(ImageList); Type GraphicsWindowType = typeof(GraphicsWindow); BitmapSource img; Primitive result = ""; try { _savedImages = (Dictionary<string, BitmapSource>)ImageListType.GetField("_savedImages", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null); if (!_savedImages.TryGetValue((string)image, out img)) return result; Bitmap dImg = FastPixel.GetBitmap(img); FastPixel fp = new FastPixel(dImg); for (int i = 0; i < fp.Width; i++) { string row = ""; for (int j = 0; j < fp.Height; j++) { Color c = fp.GetPixel(i, j); row += (j + 1).ToString() + "=" + Utilities.ArrayParse(Color2ARGB(c)) + ";"; } result[i + 1] = Utilities.CreateArrayMap(row); } fp.Unlock(false); } catch (Exception ex) { Utilities.OnError(Utilities.GetCurrentMethod(), ex); } return result; } }
/// <summary> /// Create a normal map image from a height map. The height is given by the brightness of each pixel. /// </summary> /// <param name="image">The height map ImageList image.</param> /// <param name="scale">A scale factor for the elevation (default 1).</param> /// <returns>A new ImageList image with the resulting normal map.</returns> public static Primitive HeightMap2NormalMap(Primitive image, Primitive scale) { lock (LockingVar) { Type ImageListType = typeof(ImageList); Type GraphicsWindowType = typeof(GraphicsWindow); Type ShapesType = typeof(Shapes); string normalMap = ""; BitmapSource img; try { _savedImages = (Dictionary<string, BitmapSource>)ImageListType.GetField("_savedImages", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null); if (!_savedImages.TryGetValue(image, out img)) return normalMap; MethodInfo method = ShapesType.GetMethod("GenerateNewName", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase); normalMap = method.Invoke(null, new object[] { "ImageList" }).ToString(); if (scale == "") scale = 1; Bitmap bm = FastPixel.GetBitmap(img); FastPixel fp = new FastPixel(bm); Vec3D n = new Vec3D(); double[,] height = new double[fp.Width, fp.Height]; double maxheight = 0; double minheight = 1; for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { height[i, j] = fp.GetPixel(i, j).GetBrightness(); maxheight = System.Math.Max(maxheight, height[i, j]); minheight = System.Math.Min(minheight, height[i, j]); } } if (maxheight > minheight) { for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { height[i, j] = (height[i, j] - minheight) / (maxheight - minheight); } } } for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { int im = i - 1; int ip = i + 1; int jm = j - 1; int jp = j + 1; n.Z = 1; if (im < 0) { im = 0; n.Z = 0.5f; } else if (ip >= fp.Width) { ip = fp.Width - 1; n.Z = 0.5f; } if (jm < 0) { jm = 0; n.Z = 0.5f; } else if (jp >= fp.Height) { jp = fp.Height - 1; n.Z = 0.5f; } n.X = scale * -(height[ip, jm] - height[im, jm] + 2 * (height[ip, j] - height[im, j]) + height[ip, jp] - height[im, jp]); n.Y = scale * (height[im, jp] - height[im, jm] + 2 * (height[i, jp] - height[i, jm]) + height[ip, jp] - height[ip, jm]); n.Normalize(); fp.SetPixel(i, j, Color.FromArgb(255, range((1 + n.X) * 128), range((1 + n.Y) * 128), range((1 + n.Z) * 128))); } } fp.Unlock(true); FastThread.SaveBitmap(normalMap, bm); } catch (Exception ex) { Utilities.OnError(Utilities.GetCurrentMethod(), ex); } return normalMap; } }
public static System.Drawing.Image DoEffect(System.Drawing.Image _dImg, eEffect _effect, Primitive parameter) { if (_effect == eEffect.NONE || null == _dImg) return _dImg; System.Drawing.Bitmap bmap = new System.Drawing.Bitmap(_dImg); switch (_effect) { case eEffect.NONE: //None break; case eEffect.RED: //Red { System.Drawing.Color c; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, c.R, 0, 0)); } } fp.Unlock(true); } break; case eEffect.GREEN: //Green { System.Drawing.Color c; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, 0, c.G, 0)); } } fp.Unlock(true); } break; case eEffect.BLUE: //Blue { System.Drawing.Color c; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, 0, 0, c.B)); } } fp.Unlock(true); } break; case eEffect.GRAY: //Gray { System.Drawing.Color c; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); byte gray = (byte)(.299 * c.R + .587 * c.G + .114 * c.B); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, gray, gray, gray)); } } fp.Unlock(true); } break; case eEffect.INVERSE: //Inverse { FastPixel fp = new FastPixel(bmap); System.Drawing.Color c; for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, 255 - c.R, 255 - c.G, 255 - c.B)); } } fp.Unlock(true); } break; case eEffect.YELLOW: //Yellow { System.Drawing.Color c; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); byte gray = (byte)(.299 * c.R + .587 * c.G + .114 * c.B); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, gray, gray, 0)); } } fp.Unlock(true); } break; case eEffect.CYAN: //Cyan { System.Drawing.Color c; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); byte gray = (byte)(.299 * c.R + .587 * c.G + .114 * c.B); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, 0, gray, gray)); } } fp.Unlock(true); } break; case eEffect.MAGENTA: //Magenta { System.Drawing.Color c; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); byte gray = (byte)(.299 * c.R + .587 * c.G + .114 * c.B); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, gray, 0, gray)); } } fp.Unlock(true); } break; case eEffect.SNOW: //Snow { double density = parameter; if (density <= 0) density = pEffect[(int)_effect]; Random rand = new Random(); System.Drawing.Color c; int i, j; FastPixel fp = new FastPixel(bmap); for (int ii = 0; ii < fp.Width * fp.Height / density; ii++) { i = rand.Next(fp.Width); j = rand.Next(fp.Height); c = fp.GetPixel(i, j); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, 255, 255, 255)); } fp.Unlock(true); } break; case eEffect.FUZZY: //Fuzzy { Random rand = new Random(); System.Drawing.Color c; System.Drawing.Bitmap copy = (System.Drawing.Bitmap)bmap.Clone(); FastPixel fpCopy = new FastPixel(copy); int ii, jj; int x = parameter; if (x <= 0) x = pEffect[(int)_effect]; int y = 2 * x + 1; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { ii = System.Math.Max(0, System.Math.Min(fp.Width - 1, i + rand.Next(y) - x)); jj = System.Math.Max(0, System.Math.Min(fp.Height - 1, j + rand.Next(y) - x)); c = fpCopy.GetPixel(ii, jj); fp.SetPixel(i, j, c); } } fpCopy.Unlock(false); fp.Unlock(true); } break; case eEffect.CONTRAST: //Contrast { double contrast = parameter; if (contrast <= 0) contrast = pEffect[(int)_effect]; System.Drawing.Color c; double R, G, B; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); R = c.R / 255.0 - 0.5; R = R >= 0 ? System.Math.Pow(R, 1.0 / contrast) : -System.Math.Pow(-R, 1.0 / contrast); R = 255 * (R + 0.5); R = System.Math.Max(0, System.Math.Min(255, R)); G = c.G / 255.0 - 0.5; G = G >= 0 ? System.Math.Pow(G, 1.0 / contrast) : -System.Math.Pow(-G, 1.0 / contrast); G = 255 * (G + 0.5); G = System.Math.Max(0, System.Math.Min(255, G)); B = c.B / 255.0 - 0.5; B = B >= 0 ? System.Math.Pow(B, 1.0 / contrast) : -System.Math.Pow(-B, 1.0 / contrast); B = 255 * (B + 0.5); B = System.Math.Max(0, System.Math.Min(255, B)); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, (int)R, (int)G, (int)B)); } } fp.Unlock(true); } break; case eEffect.BLOCKS: //Blocks { System.Drawing.Image.GetThumbnailImageAbort dummyCallback = new System.Drawing.Image.GetThumbnailImageAbort(ResizeAbort); int size = parameter; if (size <= 0) size = pEffect[(int)_effect]; _dImg = _dImg.GetThumbnailImage(bmap.Width / size, bmap.Height / size, dummyCallback, IntPtr.Zero); _dImg = _dImg.GetThumbnailImage(bmap.Width, bmap.Height, dummyCallback, IntPtr.Zero); bmap = new System.Drawing.Bitmap(_dImg); } break; case eEffect.REFLECT: //Reflect { int mode = parameter; if (mode <= 0) mode = pEffect[(int)_effect]; bmap.RotateFlip(mode == 1 ? System.Drawing.RotateFlipType.RotateNoneFlipY : System.Drawing.RotateFlipType.RotateNoneFlipX); } break; case eEffect.JAGGED: //Jagged { System.Drawing.Color c; System.Drawing.Bitmap copy = (System.Drawing.Bitmap)bmap.Clone(); FastPixel fpCopy = new FastPixel(copy); int amount = parameter; if (amount <= 0) amount = pEffect[(int)_effect]; bool up = true, left = false; int ii, jj; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { if (i % amount == 0) up = !up; for (int j = 0; j < fp.Height; j++) { if (j % amount == 0) left = !left; ii = left ? System.Math.Max(0, i - amount) : System.Math.Min(fp.Width - 1, i + amount); jj = up ? System.Math.Max(0, j - amount) : System.Math.Min(fp.Height - 1, j + amount); c = fpCopy.GetPixel(ii, jj); fp.SetPixel(i, j, c); } } fpCopy.Unlock(false); fp.Unlock(true); } break; case eEffect.ROTATE: //Rotate { int mode = parameter; if (mode <= 0) mode = pEffect[(int)_effect]; bmap.RotateFlip(mode == 1 ? System.Drawing.RotateFlipType.Rotate180FlipNone : mode == 2 ? System.Drawing.RotateFlipType.Rotate270FlipNone : System.Drawing.RotateFlipType.Rotate90FlipNone); } break; case eEffect.PIXELATE: //Pixelate { System.Drawing.Color c; System.Drawing.Bitmap copy = (System.Drawing.Bitmap)bmap.Clone(); int amount = parameter; if (amount <= 0) amount = pEffect[(int)_effect]; FastPixel fpCopy = new FastPixel(copy); FastPixel fp = new FastPixel(bmap); int nx = fp.Width / amount + 1; int ny = fp.Height / amount + 1; int ii, jj; int[,] A = new int[nx, ny]; int[,] R = new int[nx, ny]; int[,] G = new int[nx, ny]; int[,] B = new int[nx, ny]; int[,] N = new int[nx, ny]; System.Drawing.Color[,] C = new System.Drawing.Color[nx, ny]; for (int i = 0; i < nx; i++) { for (int j = 0; j < ny; j++) { A[i, j] = 0; R[i, j] = 0; G[i, j] = 0; B[i, j] = 0; N[i, j] = 0; } } for (int i = 0; i < fp.Width; i++) { ii = i / amount; for (int j = 0; j < fp.Height; j++) { jj = j / amount; c = fpCopy.GetPixel(i, j); A[ii, jj] += c.A; R[ii, jj] += c.R; G[ii, jj] += c.G; B[ii, jj] += c.B; N[ii, jj] += 1; fp.SetPixel(i, j, c); } } for (int i = 0; i < nx; i++) { for (int j = 0; j < ny; j++) { if (N[i,j] > 0) C[i, j] = System.Drawing.Color.FromArgb(A[i, j] / N[i, j], R[i, j] / N[i, j], G[i, j] / N[i, j], B[i, j] / N[i, j]); } } for (int i = 0; i < fp.Width; i++) { ii = i / amount; for (int j = 0; j < fp.Height; j++) { jj = j / amount; fp.SetPixel(i, j, C[ii, jj]); } } fp.Unlock(true); fpCopy.Unlock(false); } break; case eEffect.GAMMA: //Gamma { double gamma = parameter; if (gamma <= 0) gamma = pEffect[(int)_effect]; System.Drawing.Color c; double R, G, B; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); R = 255.0 * System.Math.Pow(c.R / 255.0, gamma); R = System.Math.Max(0, System.Math.Min(255, R)); G = 255.0 * System.Math.Pow(c.G / 255.0, gamma); G = System.Math.Max(0, System.Math.Min(255, G)); B = 255.0 * System.Math.Pow(c.B / 255.0, gamma); B = System.Math.Max(0, System.Math.Min(255, B)); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, (int)R, (int)G, (int)B)); } } fp.Unlock(true); } break; case eEffect.FISHEYE: //FishEye { System.Drawing.Bitmap copy = (System.Drawing.Bitmap)bmap.Clone(); double factor = parameter; if (factor < 1) factor = pEffect[(int)_effect]; factor -= 1; FastPixel fpCopy = new FastPixel(copy); FastPixel fp = new FastPixel(bmap); double centerX = fp.Width / 2; //center of distortion double centerY = fp.Height / 2; int width = fp.Width; //image bounds int height = fp.Height; xshift = calc_shift(0, centerX - 1, centerX, factor); double newcenterX = width - centerX; double xshift_2 = calc_shift(0, newcenterX - 1, newcenterX, factor); yshift = calc_shift(0, centerY - 1, centerY, factor); double newcenterY = height - centerY; double yshift_2 = calc_shift(0, newcenterY - 1, newcenterY, factor); xscale = (width - xshift - xshift_2) / width; yscale = (height - yshift - yshift_2) / height; for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { double x = getRadialX((double)i, (double)j, centerX, centerY, factor); double y = getRadialY((double)i, (double)j, centerX, centerY, factor); int ii = System.Math.Min(width - 1, System.Math.Max(0, (int)x)); int jj = System.Math.Min(height - 1, System.Math.Max(0, (int)y)); fp.SetPixel(i, j, fpCopy.GetPixel(ii, jj)); } } fp.Unlock(true); fpCopy.Unlock(false); } break; case eEffect.BULGE: //Bulge { System.Drawing.Bitmap copy = (System.Drawing.Bitmap)bmap.Clone(); double factor = parameter; if (factor <= 0) factor = pEffect[(int)_effect]; FastPixel fpCopy = new FastPixel(copy); FastPixel fp = new FastPixel(bmap); double rad = System.Math.Min(fp.Width, fp.Height) / 2.0; double dx, dy, dist, scale; int ii, jj; for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { dx = i - fp.Width / 2.0; dy = j - fp.Height / 2.0; dist = System.Math.Sqrt(dx * dx + dy * dy); scale = System.Math.Pow(dist / rad, factor) / (dist / rad); ii = (int)(fp.Width / 2.0 + scale * dx); ii = System.Math.Min(fp.Width - 1, System.Math.Max(0, ii)); jj = (int)(fp.Height / 2.0 + scale * dy); jj = System.Math.Min(fp.Height - 1, System.Math.Max(0, jj)); fp.SetPixel(i, j, fpCopy.GetPixel(ii, jj)); } } fp.Unlock(true); fpCopy.Unlock(false); } break; case eEffect.SWIRL: //Swirl { System.Drawing.Bitmap copy = (System.Drawing.Bitmap)bmap.Clone(); double factor = parameter; if (factor == 0) factor = pEffect[(int)_effect]; FastPixel fpCopy = new FastPixel(copy); FastPixel fp = new FastPixel(bmap); double dx, dy, dist, theta; int ii, jj; for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { dx = i - fp.Width / 2.0; dy = j - fp.Height / 2.0; dist = System.Math.Sqrt(dx * dx + dy * dy); if (dx == 0) theta = dy > 0 ? System.Math.PI / 2.0 : 3.0 * System.Math.PI / 2.0; else theta = System.Math.Atan(dy/dx); if (dx < 0) theta += System.Math.PI; theta += dist / fp.Width * factor * 2 * System.Math.PI; ii = (int)(fp.Width / 2.0 + dist * System.Math.Cos(theta)); ii = System.Math.Min(fp.Width - 1, System.Math.Max(0, ii)); jj = (int)(fp.Height / 2.0 + dist * System.Math.Sin(theta)); jj = System.Math.Min(fp.Height - 1, System.Math.Max(0, jj)); fp.SetPixel(i, j, fpCopy.GetPixel(ii, jj)); } } fp.Unlock(true); fpCopy.Unlock(false); } break; case eEffect.POSTERISE: //Posterise { int level = parameter; if (level <= 0) level = pEffect[(int)_effect]; System.Drawing.Color c; double R, G, B; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); R = ((int)(c.R / level)) * level; G = ((int)(c.G / level)) * level; B = ((int)(c.B / level)) * level; fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, (int)R, (int)G, (int)B)); } } fp.Unlock(true); } break; case eEffect.HUE: //Hue { double hue = parameter; if (hue <= 0) hue = pEffect[(int)_effect]; System.Drawing.Color c; double[] HSL; double[] RGB; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); HSL = LDColours.RGB2HSL(c.R, c.G, c.B); RGB = LDColours.HSL2RGB(HSL[0] + hue, HSL[1], HSL[2]); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, (int)(255*RGB[0]+0.5), (int)(255 * RGB[1] + 0.5), (int)(255 * RGB[2] + 0.5))); } } fp.Unlock(true); } break; case eEffect.SATURATION: //Saturation { double saturation = parameter; if (saturation <= 0) saturation = pEffect[(int)_effect]; System.Drawing.Color c; double[] HSL; double[] RGB; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); HSL = LDColours.RGB2HSL(c.R, c.G, c.B); RGB = LDColours.HSL2RGB(HSL[0], HSL[1] * saturation, HSL[2]); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, (int)(255 * RGB[0] + 0.5), (int)(255 * RGB[1] + 0.5), (int)(255 * RGB[2] + 0.5))); } } fp.Unlock(true); } break; case eEffect.LIGHTNESS: //Lightness { double lightness = parameter; if (lightness <= 0) lightness = pEffect[(int)_effect]; System.Drawing.Color c; double[] HSL; double[] RGB; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); HSL = LDColours.RGB2HSL(c.R, c.G, c.B); RGB = LDColours.HSL2RGB(HSL[0], HSL[1], HSL[2] * lightness); fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, (int)(255 * RGB[0] + 0.5), (int)(255 * RGB[1] + 0.5), (int)(255 * RGB[2] + 0.5))); } } fp.Unlock(true); } break; case eEffect.OILPAINT: //Oil Paint { int radius = parameter[1]; int levels = parameter[2]; if (radius <= 0) radius = pEffect[(int)_effect][1]; if (levels <= 0) levels = pEffect[(int)_effect][2]; if (radius % 2 == 0) radius++; bmap = fip.OilPaint(bmap, radius, levels); } break; case eEffect.CHARCOAL: //Charcoal { bmap = fip.SketchCharcoal(bmap); } break; case eEffect.SKETCH: //Pen sketch { bmap = fip.Sketch(bmap); } break; case eEffect.CARTOON: //Cartool { int radius = parameter[1]; int levels = parameter[2]; int inverse = parameter[3]; if (radius <= 0) radius = pEffect[(int)_effect][1]; if (levels <= 0) levels = pEffect[(int)_effect][2]; if (inverse <= 0) inverse = pEffect[(int)_effect][3]; if (radius % 2 == 0) radius++; bmap = fip.Cartoon(bmap, radius, levels, inverse); //bmap = fip.Cartoon(bmap, radius, levels, inverse, fip.LaplaceF1()); } break; case eEffect.EDGE: //Edge { bmap = fip.ImagePrewittFilterColor(bmap); //bmap = fip.ImagePrewittFilterGS(bmap); } break; case eEffect.ACCENT: //Accent { int hue = parameter[1]; int range = parameter[2]; if (hue <= 0) hue = pEffect[(int)_effect][1]; if (range <= 0) range = pEffect[(int)_effect][2]; bmap = fip.ColorAccent(bmap, hue, range); } break; case eEffect.SEPIA: //Sepia { int threshhold = parameter; if (threshhold <= 0) threshhold = pEffect[(int)_effect]; bmap = fip.Sepia(bmap, threshhold); } break; case eEffect.NOISEREMOVAL: //Noise removal { bmap = fip.ImageSDROMFilterColor(bmap); } break; case eEffect.SOLARISE: //Solarise { double power = parameter; if (power <= 0) power = pEffect[(int)_effect]; System.Drawing.Color c; double R, G, B; FastPixel fp = new FastPixel(bmap); for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { c = fp.GetPixel(i, j); R = c.R / 255.0; G = c.G / 255.0; B = c.B / 255.0; R = System.Math.Pow(R < 0.5 ? 1 - 2 * R : 2 * R - 1, power) * 255.0; G = System.Math.Pow(G < 0.5 ? 1 - 2 * G : 2 * G - 1, power) * 255.0; B = System.Math.Pow(B < 0.5 ? 1 - 2 * B : 2 * B - 1, power) * 255.0; fp.SetPixel(i, j, System.Drawing.Color.FromArgb(c.A, (int)R, (int)G, (int)B)); } } fp.Unlock(true); } break; default: break; } return (System.Drawing.Image)bmap; }
/// <summary> /// Converts ARGB images to greyscale using luminance method and calculates image convolution with given filter mask. /// </summary> /// <param name="OriginalImage">Original ARGB image</param> /// <param name="Filter">Filter mask</param> /// <returns>Filtered greyscaled image</returns> public Bitmap ImageFilterGS(Bitmap OriginalImage, int[,] Filter) { Bitmap image = OriginalImage; FastPixel fpImage = new FastPixel(image); Bitmap image2 = new Bitmap(fpImage.Width, fpImage.Height); FastPixel fpImage2 = new FastPixel(image2); if (Filter.GetLength(0) != Filter.GetLength(1)) { throw new Exception("Filter mask must be square."); } if (Filter.GetLength(0) % 2 == 0) { throw new Exception("Filter mask dimension must be odd."); } if (Filter.GetLength(0) < 3) { throw new Exception("Filter mask dimension must be greater or equal 3."); } int range = (int)Math.Floor(Convert.ToDouble(Filter.GetLength(0) / 2)); for (int m = range; m < fpImage.Width - range; m++) { for (int n = range; n < fpImage.Height - range; n++) { int[,] roi = new int[Filter.GetLength(0), Filter.GetLength(0)]; int tmpi = 0; int tmpj = 0; int newValue = 0; for (int i = m - range; i < m + range + 1; i++) { for (int j = n - range; j < n + range + 1; j++) { Color pixel = fpImage.GetPixel(i, j); Double p = Convert.ToDouble((pixel.R * 0.3) + (pixel.G * 0.59) + (pixel.B * 0.11)); roi[tmpi, tmpj] = (int)p; tmpj++; } tmpi++; tmpj = 0; } for (int k = 0; k < Filter.GetLength(0); k++) { for (int l = 0; l < Filter.GetLength(0); l++) { newValue += roi[k, l] * Filter[k, l]; } } //newValue = (int)(Convert.ToDouble(newValue)/9); if (newValue > 255) newValue = 255; if (newValue < 0) newValue = 0; fpImage2.SetPixel(m, n, Color.FromArgb(255, newValue, newValue, newValue)); } } fpImage.Unlock(false); fpImage2.Unlock(true); return image2; }