/// <summary> /// Converts an image to ASCII art /// </summary> /// <param name="Input">The image you wish to convert</param> /// <returns>A string containing the art</returns> public static string ToASCIIArt(this Bitmap Input) { if (Input == null) throw new ArgumentNullException("Input"); bool ShowLine = true; using (Bitmap TempImage = Input.BlackAndWhite()) { BitmapData OldData = TempImage.LockImage(); int OldPixelSize = OldData.GetPixelSize(); StringBuilder Builder = new StringBuilder(); for (int x = 0; x < TempImage.Height; ++x) { for (int y = 0; y < TempImage.Width; ++y) { if (ShowLine) { Color CurrentPixel = OldData.GetPixel(y, x, OldPixelSize); Builder.Append(_ASCIICharacters[((CurrentPixel.R * _ASCIICharacters.Length) / 255)]); } } if (ShowLine) { Builder.Append(System.Environment.NewLine); ShowLine = false; } else { ShowLine = true; } } TempImage.UnlockImage(OldData); return Builder.ToString(); } }
/// <summary> /// Sobel edge detection function /// </summary> /// <param name="Input">Image to manipulate</param> /// <param name="FileName">File to save to</param> /// <returns>A bitmap image</returns> public static Bitmap SobelEdgeDetection(this Bitmap Input, string FileName = "") { Input.ThrowIfNull("Input"); ImageFormat FormatUsing = FileName.GetImageFormat(); using (Bitmap TempImage = Input.BlackAndWhite()) { Filter TempFilter = new Filter(3, 3); TempFilter.MyFilter[0, 0] = -1; TempFilter.MyFilter[0, 1] = 0; TempFilter.MyFilter[0, 2] = 1; TempFilter.MyFilter[1, 0] = -2; TempFilter.MyFilter[1, 1] = 0; TempFilter.MyFilter[1, 2] = 2; TempFilter.MyFilter[2, 0] = -1; TempFilter.MyFilter[2, 1] = 0; TempFilter.MyFilter[2, 2] = 1; TempFilter.Absolute = true; using (Bitmap TempImageX = TempFilter.ApplyFilter(TempImage)) { TempFilter = new Filter(3, 3); TempFilter.MyFilter[0, 0] = 1; TempFilter.MyFilter[0, 1] = 2; TempFilter.MyFilter[0, 2] = 1; TempFilter.MyFilter[1, 0] = 0; TempFilter.MyFilter[1, 1] = 0; TempFilter.MyFilter[1, 2] = 0; TempFilter.MyFilter[2, 0] = -1; TempFilter.MyFilter[2, 1] = -2; TempFilter.MyFilter[2, 2] = -1; TempFilter.Absolute = true; using (Bitmap TempImageY = TempFilter.ApplyFilter(TempImage)) { using (Bitmap NewBitmap = new Bitmap(TempImage.Width, TempImage.Height)) { BitmapData NewData = NewBitmap.LockImage(); BitmapData OldData1 = TempImageX.LockImage(); BitmapData OldData2 = TempImageY.LockImage(); int NewPixelSize = NewData.GetPixelSize(); int OldPixelSize1 = OldData1.GetPixelSize(); int OldPixelSize2 = OldData2.GetPixelSize(); int Width = NewBitmap.Width; int Height = NewBitmap.Height; Parallel.For(0, Width, x => { for (int y = 0; y < Height; ++y) { Color Pixel1 = OldData1.GetPixel(x, y, OldPixelSize1); Color Pixel2 = OldData2.GetPixel(x, y, OldPixelSize2); NewData.SetPixel(x, y, Color.FromArgb((Pixel1.R + Pixel2.R).Clamp(255, 0), (Pixel1.G + Pixel2.G).Clamp(255, 0), (Pixel1.B + Pixel2.B).Clamp(255, 0)), NewPixelSize); } }); NewBitmap.UnlockImage(NewData); TempImageX.UnlockImage(OldData1); TempImageY.UnlockImage(OldData2); Bitmap NewBitmap2 = NewBitmap.Negative(); if (!string.IsNullOrEmpty(FileName)) NewBitmap2.Save(FileName, FormatUsing); return NewBitmap2; } } } } }
/// <summary> /// Runs a simplistic motion detection algorithm /// </summary> /// <param name="NewImage">The "new" frame</param> /// <param name="OldImage">The "old" frame</param> /// <param name="Threshold">The threshold used to detect changes in the image</param> /// <param name="DetectionColor">Color to display changes in the images as</param> /// <returns>A bitmap indicating where changes between frames have occurred overlayed on top of the new image.</returns> public static Bitmap MotionDetection(this Bitmap NewImage, Bitmap OldImage, int Threshold, Color DetectionColor) { NewImage.ThrowIfNull("NewImage"); OldImage.ThrowIfNull("OldImage"); DetectionColor.ThrowIfNull("DetectionColor"); using (Bitmap NewImage1 = NewImage.BlackAndWhite()) { using (Bitmap OldImage1 = OldImage.BlackAndWhite()) { using (Bitmap NewImage2 = NewImage1.SNNBlur(5)) { using (Bitmap OldImage2 = OldImage1.SNNBlur(5)) { using (Bitmap OutputImage = new Bitmap(NewImage2, NewImage2.Width, NewImage2.Height)) { using (Bitmap Overlay = new Bitmap(NewImage, NewImage.Width, NewImage.Height)) { BitmapData NewImage2Data = NewImage2.LockImage(); int NewImage2PixelSize = NewImage2Data.GetPixelSize(); BitmapData OldImage2Data = OldImage2.LockImage(); int OldImage2PixelSize = OldImage2Data.GetPixelSize(); BitmapData OverlayData = Overlay.LockImage(); int OverlayPixelSize = OverlayData.GetPixelSize(); int Width = OutputImage.Width; int Height = OutputImage.Height; Parallel.For(0, Width, x => { for (int y = 0; y < Height; ++y) { Color NewPixel = NewImage2Data.GetPixel(x, y, NewImage2PixelSize); Color OldPixel = OldImage2Data.GetPixel(x, y, OldImage2PixelSize); if (System.Math.Pow((double)(NewPixel.R - OldPixel.R), 2.0) > Threshold) { OverlayData.SetPixel(x, y, Color.FromArgb(100, 0, 100), OverlayPixelSize); } else { OverlayData.SetPixel(x, y, Color.FromArgb(200, 0, 200), OverlayPixelSize); } } }); Overlay.UnlockImage(OverlayData); NewImage2.UnlockImage(NewImage2Data); OldImage2.UnlockImage(OldImage2Data); using (Bitmap Overlay2 = Overlay.EdgeDetection(25, DetectionColor)) { BitmapData Overlay2Data = Overlay2.LockImage(); int Overlay2PixelSize = Overlay2Data.GetPixelSize(); Width = OutputImage.Width; Height = OutputImage.Height; Parallel.For(0, Width, x => { for (int y = 0; y < Height; ++y) { Color Pixel1 = Overlay2Data.GetPixel(x, y, Overlay2PixelSize); if (Pixel1.R != DetectionColor.R || Pixel1.G != DetectionColor.G || Pixel1.B != DetectionColor.B) { Overlay2Data.SetPixel(x, y, Color.FromArgb(200, 0, 200), Overlay2PixelSize); } } }); Overlay2.UnlockImage(Overlay2Data); return OutputImage.Watermark(Overlay2, 1.0f, 0, 0, Color.FromArgb(200, 0, 200)); } } } } } } } }
/// <summary> /// Laplace edge detection function /// </summary> /// <param name="Image">Image to manipulate</param> /// <param name="FileName">File to save to</param> /// <returns>A bitmap object</returns> public static Bitmap LaplaceEdgeDetection(this Bitmap Image, string FileName = "") { Image.ThrowIfNull("Image"); ImageFormat FormatUsing = FileName.GetImageFormat(); using (Bitmap TempImage = Image.BlackAndWhite()) { Filter TempFilter = new Filter(5, 5); TempFilter.MyFilter[0, 0] = -1; TempFilter.MyFilter[0, 1] = -1; TempFilter.MyFilter[0, 2] = -1; TempFilter.MyFilter[0, 3] = -1; TempFilter.MyFilter[0, 4] = -1; TempFilter.MyFilter[1, 0] = -1; TempFilter.MyFilter[1, 1] = -1; TempFilter.MyFilter[1, 2] = -1; TempFilter.MyFilter[1, 3] = -1; TempFilter.MyFilter[1, 4] = -1; TempFilter.MyFilter[2, 0] = -1; TempFilter.MyFilter[2, 1] = -1; TempFilter.MyFilter[2, 2] = 24; TempFilter.MyFilter[2, 3] = -1; TempFilter.MyFilter[2, 4] = -1; TempFilter.MyFilter[3, 0] = -1; TempFilter.MyFilter[3, 1] = -1; TempFilter.MyFilter[3, 2] = -1; TempFilter.MyFilter[3, 3] = -1; TempFilter.MyFilter[3, 4] = -1; TempFilter.MyFilter[4, 0] = -1; TempFilter.MyFilter[4, 1] = -1; TempFilter.MyFilter[4, 2] = -1; TempFilter.MyFilter[4, 3] = -1; TempFilter.MyFilter[4, 4] = -1; using (Bitmap NewImage = TempFilter.ApplyFilter(TempImage)) { Bitmap NewBitmap = NewImage.Negative(); if (!string.IsNullOrEmpty(FileName)) NewBitmap.Save(FileName, FormatUsing); return NewBitmap; } } }
/// <summary> /// Laplace edge detection function /// </summary> /// <param name="Image">Image to manipulate</param> /// <returns>A SwiftBitmap object</returns> public static SwiftBitmap LaplaceEdgeDetection(this SwiftBitmap Image) { Contract.Requires<ArgumentNullException>(Image != null, "Image"); return Image.BlackAndWhite().ApplyConvolutionFilter(new int[][]{ new int[] {-1, -1, -1, -1, -1}, new int[] {-1, -1, -1, -1, -1}, new int[] {-1, -1, 24, -1, -1}, new int[] {-1, -1, -1, -1, -1}, new int[] {-1, -1, -1, -1, -1}, }); }
/// <summary> /// Sobel edge detection function /// </summary> /// <param name="Input">Image to manipulate</param> /// <returns>A SwiftBitmap image</returns> public static SwiftBitmap SobelEdgeDetection(this SwiftBitmap Input) { Contract.Requires<ArgumentNullException>(Input != null, "Input"); Input.BlackAndWhite(); using (SwiftBitmap TempImageX = ((SwiftBitmap)Input.Clone()).ApplyConvolutionFilter(new int[][]{ new int[] {-1, 0, 1}, new int[] {-2, 0, 2}, new int[] {-1, 0, 1} }, true)) { using (SwiftBitmap TempImageY = ((SwiftBitmap)Input.Clone()).ApplyConvolutionFilter(new int[][]{ new int[] {1, 2, 1}, new int[] {0, 0, 0}, new int[] {-1, -2, -1} }, true)) { using (SwiftBitmap NewBitmap = new SwiftBitmap(Input.Width, Input.Height)) { NewBitmap.Lock(); TempImageX.Lock(); TempImageY.Lock(); int Width = NewBitmap.Width; int Height = NewBitmap.Height; Parallel.For(0, Width, x => { for (int y = 0; y < Height; ++y) { Color Pixel1 = TempImageX.GetPixel(x, y); Color Pixel2 = TempImageY.GetPixel(x, y); NewBitmap.SetPixel(x, y, Color.FromArgb((Pixel1.R + Pixel2.R).Clamp(255, 0), (Pixel1.G + Pixel2.G).Clamp(255, 0), (Pixel1.B + Pixel2.B).Clamp(255, 0))); } }); NewBitmap.Unlock(); TempImageY.Unlock(); TempImageX.Unlock(); return Input.Copy(NewBitmap).Negative(); } } } }