/// <summary> /// add two images /// </summary> /// <param name="img"> /// ref Image /// </param> /// <param name="summand"> /// image to add /// </param> public static void Add(ref ImageData img, ImageData summand) { if((img.Width == summand.Width) && (img.Height == summand.Height)) { for(int column = 0; column < summand.Width; column++) { for(int row = 0; row < summand.Height; row++) { Color a = summand[column, row]; Color b = img[column, row]; int cr = a.R + b.R; int cg = a.G + b.G; int cb = a.B + b.B; if(cr > 255) { cr -= 255; } if(cg > 255) { cg -= 255; } if(cb > 255) { cb -= 255; } img[column, row] = Color.FromArgb(cr, cg, cb); } } } }
/// <summary> /// Get the average rgb-values from an image in a given rectangle /// By default the function calculate the average rgb-values from the whole image /// </summary> /// <param name="img"> /// Image /// </param> /// <param name="left"> /// left of rectangle (default=0) /// </param> /// <param name="top"> /// top of rectangle (default=0) /// </param> /// <param name="width"> /// width of rectangle (default=full width) /// </param> /// <param name="height"> /// height of rectangle (default=full height) /// </param> /// <returns> /// averag rgb-values /// </returns> public static double[] AverageRgbValues(ImageData img, int left = 0, int top = 0, int width = -1, int height = -1) { long[] totals = { 0, 0, 0 }; if(width == -1) { width = img.Width; } if(height == -1) { height = img.Height; } for(int x = left; x < left + width; x++) { for(int y = top; y < top + height; y++) { Color currentColor = img.GetPixel(x, y); totals[0] += currentColor.R; totals[1] += currentColor.G; totals[2] += currentColor.B; } } int count = width * height; double[] retvar = { totals[0] / (double)count, totals[1] / (double)count, totals[2] / (double)count }; return retvar; }
/// <summary> /// search for an image in another image /// return all possible matchings /// </summary> /// <param name="img"> /// image to look in /// </param> /// <param name="Ref"> /// image to look for /// </param> /// <param name="tolerance"> /// tolerance of similarity (0,...,255) /// </param> /// <returns> /// List of matching positions (datatype Rectange) /// </returns> public static List<Rectangle> AllImages(ImageData img, ImageData Ref, uint tolerance = 0) { List<Rectangle> retVal = new List<Rectangle>(); for(int originalX = 0; originalX < img.Width - Ref.Width; originalX++) { for(int originalY = 0; originalY < img.Height - Ref.Height; originalY++) { Color currentInnerPictureColor = Ref[0, 0]; Color currentOuterPictureColor = img[originalX, originalY]; if(!CommonFunctions.ColorsSimilar(currentInnerPictureColor, currentOuterPictureColor, tolerance)) { continue; } bool allSimilar = true; for(int referenceX = 0; referenceX < Ref.Width; referenceX++) { if(!allSimilar) { break; } for(int referenceY = 0; referenceY < Ref.Height; referenceY++) { if(!allSimilar) { break; } currentInnerPictureColor = Ref[referenceX, referenceY]; currentOuterPictureColor = img[originalX + referenceX, originalY + referenceY]; if(!CommonFunctions.ColorsSimilar(currentInnerPictureColor, currentOuterPictureColor, tolerance)) { allSimilar = false; } } } if(allSimilar) { retVal.Add(new Rectangle(originalX, originalY, Ref.Width, Ref.Height)); } } } return retVal; }
/// <summary> /// sharpen an image /// </summary> /// <param name="img"> /// image to manipulate /// </param> /// <param name="weight"> /// weight /// </param> public static void Sharpen(ref ImageData img, double weight) { ConvolutionMatrix cMatrix = new ConvolutionMatrix(3); cMatrix.SetAll(1); cMatrix.Matrix[0, 0] = 0; cMatrix.Matrix[1, 0] = -2; cMatrix.Matrix[2, 0] = 0; cMatrix.Matrix[0, 1] = -2; cMatrix.Matrix[1, 1] = weight; cMatrix.Matrix[2, 1] = -2; cMatrix.Matrix[0, 2] = 0; cMatrix.Matrix[1, 2] = -2; cMatrix.Matrix[2, 2] = 0; cMatrix.Factor = weight - 8; ApplyConvolution3X3(ref img, cMatrix); }
/// <summary> /// Convert image to sepia /// </summary> /// <param name="img"> /// ref image to convert /// </param> public static void Sepia(ref ImageData img) { for(int column = 0; column < img.Width; column++) { for(int row = 0; row < img.Height; row++) { Color c = img[column, row]; int t = Convert.ToInt32(0.299 * c.R + 0.587 * c.G + 0.114 * c.B); img.SetPixel(column, row, Color.FromArgb((t > 206) ? 255 : t + 49, (t < 14) ? 0 : t - 14, (t < 56) ? 0 : t - 56)); } } }
/// <summary> /// search for an image in another image /// return the best matching position /// </summary> /// <param name="img"> /// image to look in /// </param> /// <param name="Ref"> /// image to look for /// </param> /// <param name="tolerance"> /// tolerance of similarity (0,...,255) /// </param> /// <returns> /// best matching position as rectangle /// </returns> public static Rectangle Image(ImageData img, ImageData Ref, uint tolerance = 0) { double bestScore = Math.Abs(byte.MaxValue - byte.MinValue) * 3; Point location = Point.Empty; bool found = false; for(int originalX = 0; originalX < img.Width - Ref.Width; originalX++) { for(int originalY = 0; originalY < img.Height - Ref.Height; originalY++) { Color currentInnerPictureColor = Ref[0, 0]; Color currentOuterPictureColor = img[originalX, originalY]; if(!CommonFunctions.ColorsSimilar(currentInnerPictureColor, currentOuterPictureColor, tolerance)) { continue; } int currentScore = 0; bool allSimilar = true; for(int referenceX = 0; referenceX < Ref.Width; referenceX++) { if(!allSimilar) { break; } for(int referenceY = 0; referenceY < Ref.Height; referenceY++) { if(!allSimilar) { break; } currentInnerPictureColor = Ref[referenceX, referenceY]; currentOuterPictureColor = img[originalX + referenceX, originalY + referenceY]; if(!CommonFunctions.ColorsSimilar(currentInnerPictureColor, currentOuterPictureColor, tolerance)) { allSimilar = false; } currentScore += Math.Abs(currentInnerPictureColor.R - currentOuterPictureColor.R) + Math.Abs(currentInnerPictureColor.G - currentOuterPictureColor.G) + Math.Abs(currentInnerPictureColor.B - currentOuterPictureColor.B); } } if(allSimilar) { if((currentScore / (double)(Ref.Width * Ref.Height)) < bestScore) { location.X = originalX; location.Y = originalY; bestScore = currentScore / (double)(Ref.Width * Ref.Height); found = true; } } } } return found ? new Rectangle(location.X, location.Y, Ref.Width, Ref.Height) : Rectangle.Empty; }
/// <summary> /// Get the average color from an image in a given rectangle /// By default the function calculate the average color from the whole image /// </summary> /// <param name="img"> /// Image /// </param> /// <param name="left"> /// left of rectangle (default=0) /// </param> /// <param name="top"> /// top of rectangle (default=0) /// </param> /// <param name="width"> /// width of rectangle (default=full width) /// </param> /// <param name="height"> /// height of rectangle (default=full height) /// </param> /// <returns> /// average color /// </returns> public static Color AverageColor(ImageData img, int left = 0, int top = 0, int width = -1, int height = -1) { double[] retvar = AverageRgbValues(img, left, top, width, height); return Color.FromArgb(Convert.ToInt32(retvar[0]), Convert.ToInt32(retvar[1]), Convert.ToInt32(retvar[2])); }
/// <summary> /// identify image from list (choose the image with best matching) /// </summary> /// <param name="img"> /// image to look for /// </param> /// <param name="statReference"> /// list of reference images /// </param> /// <returns> /// name (key of list) /// </returns> public static string IdentifyImage(ImageData img, Dictionary<string, ImageData> statReference) { double similar = 0.0; string keyword = string.Empty; foreach(KeyValuePair<string, ImageData> item in statReference) { // exakte übereinstimmung der Größen ermöglicht einen simplen vergleich if((img.Width == item.Value.Width) && (img.Height == item.Value.Height)) { double s = Similarity(img, item.Value); if(s > similar) { keyword = item.Key; similar = s; } } else { if((img.Width > item.Value.Width) && (img.Height > item.Value.Height)) { // im größeren suchen for(int column = 0; column < img.Width - item.Value.Width; column++) { for(int row = 0; row < img.Height - item.Value.Height; row++) { double s = Similarity(img, item.Value, 0, 0, item.Value.Width, item.Value.Height, column, row); if(s > similar) { keyword = item.Key; similar = s; } } } } } } return keyword; }
/// <summary> /// change the brightness of an image /// </summary> /// <param name="img"> /// image to manipulate /// </param> /// <param name="brightness"> /// brightness of new image /// </param> public static void Brightness(ref ImageData img, int brightness) { for(int y = 0; y < img.Height; y++) { for(int x = 0; x < img.Width; x++) { Color pixelColor = img[x, y]; int redChannel = pixelColor.R + brightness; int greenChannel = pixelColor.G + brightness; int blueChannel = pixelColor.B + brightness; redChannel = (redChannel > 255) ? 255 : redChannel; redChannel = (redChannel < 0) ? 0 : redChannel; greenChannel = (greenChannel > 255) ? 255 : greenChannel; greenChannel = (greenChannel < 0) ? 0 : greenChannel; blueChannel = (blueChannel > 255) ? 255 : blueChannel; blueChannel = (blueChannel < 0) ? 0 : blueChannel; img.SetPixel(x, y, Color.FromArgb(redChannel, greenChannel, blueChannel)); } } }
/// <summary> /// black and white image by replace /// all similar color to black by blackand /// all similiar colors to white by white /// </summary> /// <param name="img"> /// ref image /// </param> /// <param name="tolerance"> /// tolerance (0,...,255) /// </param> public static void BlackAndWhite(ref ImageData img, uint tolerance) { ReplaceSimilarColor(ref img, Color.Black, Color.Black, tolerance); ReplaceDifferentColor(ref img, Color.Black, Color.White, tolerance); }
/// <summary> /// apply gaussianblur to image /// </summary> /// <param name="img"> /// image to manipulate /// </param> /// <param name="peakValue"> /// parameter /// </param> public static void GaussianBlur(ref ImageData img, double peakValue) { ConvolutionMatrix cMatrix = new ConvolutionMatrix(3); cMatrix.SetAll(1); cMatrix.Matrix[0, 0] = peakValue / 4; cMatrix.Matrix[1, 0] = peakValue / 2; cMatrix.Matrix[2, 0] = peakValue / 4; cMatrix.Matrix[0, 1] = peakValue / 2; cMatrix.Matrix[1, 1] = peakValue; cMatrix.Matrix[2, 1] = peakValue / 2; cMatrix.Matrix[0, 2] = peakValue / 4; cMatrix.Matrix[1, 2] = peakValue / 2; cMatrix.Matrix[2, 2] = peakValue / 4; cMatrix.Factor = peakValue * 4; ApplyConvolution3X3(ref img, cMatrix); }
/// <summary> /// marks the edges black and all other pixels white /// </summary> /// <param name="img"> /// image to manipulate /// </param> public static void FindEdges(ref ImageData img) { Emboss(ref img, 4.0); ReplaceSimilarColor(ref img, Color.FromArgb(127, 132, 127), Color.White, 20); ReplaceDifferentColor(ref img, Color.White, Color.Black, 1); }
/// <summary> /// apply emboss effect on image /// </summary> /// <param name="img"> /// image to manipulate /// </param> /// <param name="weight"> /// weight of emboss effect /// </param> public static void Emboss(ref ImageData img, double weight) { ConvolutionMatrix cMatrix = new ConvolutionMatrix(3); cMatrix.SetAll(1); cMatrix.Matrix[0, 0] = -1; cMatrix.Matrix[1, 0] = 0; cMatrix.Matrix[2, 0] = -1; cMatrix.Matrix[0, 1] = 0; cMatrix.Matrix[1, 1] = weight; cMatrix.Matrix[2, 1] = 0; cMatrix.Matrix[0, 2] = -1; cMatrix.Matrix[1, 2] = 0; cMatrix.Matrix[2, 2] = -1; cMatrix.Factor = 4; cMatrix.Offset = 127; ApplyConvolution3X3(ref img, cMatrix); }
/// <summary> /// subtract two images /// </summary> /// <param name="img"> /// ref images /// </param> /// <param name="subtrahend"> /// subtrahend /// </param> public static void Difference(ref ImageData img, ImageData subtrahend) { if((img.Width == subtrahend.Width) && (img.Height == subtrahend.Height)) { for(int column = 0; column < subtrahend.Width; column++) { for(int row = 0; row < subtrahend.Height; row++) { Color a = subtrahend[column, row]; Color b = img[column, row]; int cr = a.R - b.R; int cg = a.G - b.G; int cb = a.B - b.B; if(cr < 0) { cr += 255; } if(cg < 0) { cg += 255; } if(cb < 0) { cb += 255; } img[column, row] = Color.FromArgb(cr, cg, cb); } } } }
/// <summary> /// decrease the depth of color /// </summary> /// <param name="img"> /// image to manipulate /// </param> /// <param name="offset"> /// offset of colordepth /// </param> public static void DecreaseColourDepth(ref ImageData img, int offset) { for(int y = 0; y < img.Height; y++) { for(int x = 0; x < img.Width; x++) { Color pixelColor = img[x, y]; int redChannel = (pixelColor.R + (offset / 2)) - ((pixelColor.R + (offset / 2)) % offset) - 1; int greenChannel = (pixelColor.G + (offset / 2)) - ((pixelColor.G + (offset / 2)) % offset) - 1; int blueChannel = (pixelColor.B + (offset / 2)) - ((pixelColor.B + (offset / 2)) % offset) - 1; redChannel = (redChannel < 0) ? 0 : redChannel; greenChannel = (greenChannel < 0) ? 0 : greenChannel; blueChannel = (blueChannel < 0) ? 0 : blueChannel; img.SetPixel(x, y, Color.FromArgb(redChannel, greenChannel, blueChannel)); } } }
/// <summary> /// change the contrast of an image /// </summary> /// <param name="img"> /// image to manipilate /// </param> /// <param name="contrast"> /// value of contrast /// </param> public static void Contrast(ref ImageData img, double contrast) { contrast = (100.0 + contrast) / 100.0; contrast *= contrast; for(int y = 0; y < img.Height; y++) { for(int x = 0; x < img.Width; x++) { Color pixelColor = img[x, y]; double redChannel = (((pixelColor.R / 255.0) - 0.5) * contrast + 0.5) * 255; double greenChannel = (((pixelColor.G / 255.0) - 0.5) * contrast + 0.5) * 255; double blueChannel = (((pixelColor.B / 255.0) - 0.5) * contrast + 0.5) * 255; redChannel = (redChannel > 255) ? 255 : redChannel; redChannel = (redChannel < 0) ? 0 : redChannel; greenChannel = (greenChannel > 255) ? 255 : greenChannel; greenChannel = (greenChannel < 0) ? 0 : greenChannel; blueChannel = (blueChannel > 255) ? 255 : blueChannel; blueChannel = (blueChannel < 0) ? 0 : blueChannel; img.SetPixel(x, y, Color.FromArgb((int)redChannel, (int)greenChannel, (int)blueChannel)); } } }
/// <summary> /// apply threshold /// </summary> /// <param name="img"> /// ref Image /// </param> /// <param name="threshold"> /// threshold (0,...,255) /// </param> public static void Threshold(ref ImageData img, uint threshold) { for(int column = 0; column < img.Width; column++) { for(int row = 0; row < img.Height; row++) { Color c = img[column, row]; if(c.R > threshold) { img[column, row] = Color.White; } else { img[column, row] = Color.Black; } } } }
/// <summary> /// The apply convolution 3 x 3. /// </summary> /// <param name="img"> /// The img. /// </param> /// <param name="matrix"> /// The matrix. /// </param> private static void ApplyConvolution3X3(ref ImageData img, ConvolutionMatrix matrix) { ImageData newImg = img.Clone(); Color[,] pixelColor = new Color[3, 3]; for(int y = 0; y < img.Height - 2; y++) { for(int x = 0; x < img.Width - 2; x++) { pixelColor[0, 0] = img[x, y]; pixelColor[0, 1] = img[x, y + 1]; pixelColor[0, 2] = img[x, y + 2]; pixelColor[1, 0] = img[x + 1, y]; pixelColor[1, 1] = img[x + 1, y + 1]; pixelColor[1, 2] = img[x + 1, y + 2]; pixelColor[2, 0] = img[x + 2, y]; pixelColor[2, 1] = img[x + 2, y + 1]; pixelColor[2, 2] = img[x + 2, y + 2]; int alphaChannel = pixelColor[1, 1].A; int redChannel = (int) ((((pixelColor[0, 0].R * matrix.Matrix[0, 0]) + (pixelColor[1, 0].R * matrix.Matrix[1, 0]) + (pixelColor[2, 0].R * matrix.Matrix[2, 0]) + (pixelColor[0, 1].R * matrix.Matrix[0, 1]) + (pixelColor[1, 1].R * matrix.Matrix[1, 1]) + (pixelColor[2, 1].R * matrix.Matrix[2, 1]) + (pixelColor[0, 2].R * matrix.Matrix[0, 2]) + (pixelColor[1, 2].R * matrix.Matrix[1, 2]) + (pixelColor[2, 2].R * matrix.Matrix[2, 2])) / matrix.Factor) + matrix.Offset); int greenChannel = (int) ((((pixelColor[0, 0].G * matrix.Matrix[0, 0]) + (pixelColor[1, 0].G * matrix.Matrix[1, 0]) + (pixelColor[2, 0].G * matrix.Matrix[2, 0]) + (pixelColor[0, 1].G * matrix.Matrix[0, 1]) + (pixelColor[1, 1].G * matrix.Matrix[1, 1]) + (pixelColor[2, 1].G * matrix.Matrix[2, 1]) + (pixelColor[0, 2].G * matrix.Matrix[0, 2]) + (pixelColor[1, 2].G * matrix.Matrix[1, 2]) + (pixelColor[2, 2].G * matrix.Matrix[2, 2])) / matrix.Factor) + matrix.Offset); int blueChannel = (int) ((((pixelColor[0, 0].B * matrix.Matrix[0, 0]) + (pixelColor[1, 0].B * matrix.Matrix[1, 0]) + (pixelColor[2, 0].B * matrix.Matrix[2, 0]) + (pixelColor[0, 1].B * matrix.Matrix[0, 1]) + (pixelColor[1, 1].B * matrix.Matrix[1, 1]) + (pixelColor[2, 1].B * matrix.Matrix[2, 1]) + (pixelColor[0, 2].B * matrix.Matrix[0, 2]) + (pixelColor[1, 2].B * matrix.Matrix[1, 2]) + (pixelColor[2, 2].B * matrix.Matrix[2, 2])) / matrix.Factor) + matrix.Offset); redChannel = (redChannel > 255) ? 255 : redChannel; redChannel = (redChannel < 0) ? 0 : redChannel; greenChannel = (greenChannel > 255) ? 255 : greenChannel; greenChannel = (greenChannel < 0) ? 0 : greenChannel; blueChannel = (blueChannel > 255) ? 255 : blueChannel; blueChannel = (blueChannel < 0) ? 0 : blueChannel; newImg.SetPixel(x + 1, y + 1, Color.FromArgb(alphaChannel, redChannel, greenChannel, blueChannel)); } } img = newImg.Clone(); }
/// <summary> /// Initializes a new instance of the <see cref="ImageData" /> class. /// creates a new imagedata object from another imagedata object /// </summary> /// <param name="img"> /// The Img. /// </param> public ImageData(ImageData img) { this.LoadBitmap(img.Bitmap); }
/// <summary> /// blur the image /// </summary> /// <param name="img"> /// image to manipulate /// </param> /// <param name="weight"> /// weight of effect /// </param> public static void Blur(ref ImageData img, double weight) { ConvolutionMatrix cMatrix = new ConvolutionMatrix(3); cMatrix.SetAll(1); cMatrix.Matrix[1, 1] = weight; cMatrix.Factor = weight + 8; ApplyConvolution3X3(ref img, cMatrix); }
/// <summary> /// find first occurence of color with tolerance /// </summary> /// <param name="img"> /// image to look in /// </param> /// <param name="searchColor"> /// color to look for /// </param> /// <param name="tolerance"> /// tolerance /// </param> /// <returns> /// The <see cref="bool" /> 2dim array. /// </returns> public static bool[,] FindColors(ImageData img, Color searchColor, uint tolerance) { bool[,] grid = new bool[img.Width, img.Height]; for(int column = 0; column < img.Width; column++) { for(int row = 0; row < img.Height; row++) { if(ColorsSimilar(img.GetPixel(column, row), searchColor, tolerance)) { grid[column, row] = true; } else { grid[column, row] = false; } } } return grid; }
/// <summary> /// get the red channel as array /// </summary> /// <param name="img"> /// image /// </param> /// <returns> /// array[] of red channel /// </returns> public static uint[,] ExtractRedChannel(ImageData img) { uint[,] red = new uint[img.Width, img.Height]; for(int column = 0; column < img.Width; column++) { for(int row = 0; row < img.Height; row++) { Color c = img.GetPixel(column, row); red[column, row] = c.R; } } return red; }
/// <summary> /// Convert image to grayscale /// </summary> /// <param name="img"> /// ref image to convert /// </param> public static void Grayscale(ref ImageData img) { for(int column = 0; column < img.Width; column++) { for(int row = 0; row < img.Height; row++) { Color c = img[column, row]; int grayScale = (int)((c.R * .3) + (c.G * .59) + (c.B * .11)); img[column, row] = Color.FromArgb(grayScale, grayScale, grayScale); } } }
/// <summary> /// identify the color of a part(rectangle) from an image by a given list of reference colors /// </summary> /// <param name="img"> /// image to look in /// </param> /// <param name="statReference"> /// list of possible colors /// </param> /// <param name="left"> /// left of rectangle (default: 0) /// </param> /// <param name="top"> /// top of rectangle (default: 0) /// </param> /// <param name="width"> /// width of rectangle (default: full width) /// </param> /// <param name="height"> /// height of rectangle (default: full height) /// </param> /// <returns> /// Color /// </returns> public static Color IdentifyColor( ImageData img, Dictionary<Color, List<double>> statReference, int left = 0, int top = 0, int width = -1, int height = -1) { double[] av = AverageRgbValues(img, left, top, width, height); double bestScore = 255; Color foo = Color.White; foreach(KeyValuePair<Color, List<double>> item in statReference) { double currentScore = Math.Pow((item.Value[0] / 255.0) - (av[0] / 255.0), 2) + Math.Pow((item.Value[1] / 255.0) - (av[1] / 255.0), 2) + Math.Pow((item.Value[2] / 255.0) - (av[2] / 255.0), 2); if(currentScore < bestScore) { foo = item.Key; bestScore = currentScore; } } return foo; }
/// <summary> /// invert image /// </summary> /// <param name="img"> /// ref image to convert /// </param> public static void Invert(ref ImageData img) { for(int column = 0; column < img.Width; column++) { for(int row = 0; row < img.Height; row++) { Color c = img[column, row]; img[column, row] = Color.FromArgb(255 - c.R, 255 - c.G, 255 - c.B); } } }
/// <summary> /// calculate the similarity of image A in a given rectangle and a reference image B /// </summary> /// <param name="img"> /// image A /// </param> /// <param name="reference"> /// image B /// </param> /// <param name="left"> /// offset from left of image A /// </param> /// <param name="top"> /// offset from top of image A /// </param> /// <param name="width"> /// width of rectangle (default: full width) /// </param> /// <param name="height"> /// height of rectangle (default: full height) /// </param> /// <param name="offsetLeft"> /// The Offset Left. /// </param> /// <param name="offsetTop"> /// The Offset Top. /// </param> /// <returns> /// similarity (1=exact,0=none) /// </returns> public static double Similarity( ImageData img, ImageData reference, int left = 0, int top = 0, int width = -1, int height = -1, int offsetLeft = 0, int offsetTop = 0) { double sim = 0.0; width = (width == -1) ? img.Width - left : width; height = (height == -1) ? img.Height - top : height; if((img.Width == reference.Width) && (img.Height == reference.Height)) { for(int column = left; column < left + width; column++) { for(int row = top; row < top + height; row++) { Color a = img.GetPixel(offsetLeft + column, offsetTop + row); Color b = reference.GetPixel(column, row); int cr = Math.Abs(a.R - b.R); int cg = Math.Abs(a.G - b.G); int cb = Math.Abs(a.B - b.B); sim += (cr + cg + cb) / 3.0; } } sim /= 255.0; sim /= img.Height * img.Width; } return 1 - sim; }
/// <summary> /// mark a point in image /// </summary> /// <param name="img"> /// ref image to mark /// </param> /// <param name="location"> /// where to set marker /// </param> /// <param name="markColor"> /// color of marker /// </param> /// <param name="size"> /// size of marker (square) /// </param> public static void MarkPoint(ref ImageData img, Point location, Color markColor, uint size = 5) { for(int i = Convert.ToInt32(location.X - size); i < location.X + size; i++) { for(int j = Convert.ToInt32(location.Y - size); j < location.Y + size; j++) { img[i, j] = markColor; } } }
/// <summary> /// replace color by another color /// </summary> /// <param name="img"> /// ref Image /// </param> /// <param name="searchColor"> /// color to look for /// </param> /// <param name="replaceColor"> /// color to replace with /// </param> /// <param name="tolerance"> /// tolerance of reference color (0,...,255) /// </param> public static void ReplaceSimilarColor(ref ImageData img, Color searchColor, Color replaceColor, uint tolerance) { for(int outerX = 0; outerX < img.Width; outerX++) { for(int outerY = 0; outerY < img.Height; outerY++) { Color a = img[outerX, outerY]; if(CommonFunctions.ColorsSimilar(a, searchColor, tolerance)) { img[outerX, outerY] = replaceColor; } } } }
/// <summary> /// search for binary patterns /// </summary> /// <param name="img"> /// image to look in /// </param> /// <param name="pattern"> /// pattern to look for /// </param> /// <param name="tolerance"> /// tolerance (0,...,255) /// </param> /// <returns> /// The <see cref="Rectangle" />. /// </returns> public static Rectangle BinaryPattern(ImageData img, bool[,] pattern, uint tolerance = 0) { // simple Point location = Point.Empty; Color referenceColor = Color.Wheat; bool first = true; for(int outerColumn = 0; outerColumn < img.Width - pattern.GetLength(1); outerColumn++) { for(int outerRow = 0; outerRow < img.Height - pattern.GetLength(0); outerRow++) { for(int innerColumn = 0; innerColumn < pattern.GetLength(1); innerColumn++) { for(int innerRow = 0; innerRow < pattern.GetLength(0); innerRow++) { if(pattern[innerRow, innerColumn]) { if(first) { referenceColor = img[outerColumn, outerRow]; first = false; } else { if(CommonFunctions.ColorsSimilar( referenceColor, img[outerColumn + innerColumn, outerRow + innerRow], tolerance)) { // ok } else { // schlecht passt nicht innerColumn = pattern.GetLength(1) + 10; first = true; break; } } } else { if(first == false) { // darf nicht passen! if(CommonFunctions.ColorsSimilar( referenceColor, img[outerColumn + innerColumn, outerRow + innerRow], tolerance)) { // schlecht passt innerColumn = img.Width + 10; innerRow = img.Height + 10; first = true; } } } } } if(first == false) { // matched location.X = outerColumn; location.Y = outerRow; return new Rectangle(location.X, location.Y, pattern.GetLength(1), pattern.GetLength(0)); } } } return Rectangle.Empty; }