public static Bitmap ToWhiteBorder(System.Drawing.Bitmap bmpOriginal, System.Drawing.KnownColor knownColor) { System.Drawing.Color subColor = GetCompatibleColor(knownColor); Bitmap bmp = CreateNonIndexedImage(bmpOriginal); System.Drawing.Size size = bmp.Size; isBlack = new bool[bmp.Width, bmp.Height]; wasChecked = new bool[bmp.Width, bmp.Height]; alreadyAdded = new bool[bmp.Width, bmp.Height]; bool[,] isContiguous = new bool[bmp.Width, bmp.Height]; pixels = new Color[bmp.Width, bmp.Height]; for (int x = 0; x < bmp.Width; x++) { for (int y = 0; y < bmp.Height; y++) { isBlack[x, y] = false; wasChecked[x, y] = false; alreadyAdded[x, y] = false; pixels[x, y] = bmp.GetPixel(x, y); } } bmpSize = bmp.Size; List <Point> continguousEdges = new List <Point>(); Point startPoint = new Point(5, 5); continguousEdges.Add(startPoint); Point topRight = new Point(bmp.Width - 5, 5); continguousEdges.Add(topRight); Point bottomRight = new Point(bmp.Width - 5, bmp.Height - 5); continguousEdges.Add(bottomRight); bool pointAdded = true; while (continguousEdges.Count > 0) { pointAdded = false; if (continguousEdges.Count > 0) { Point point = continguousEdges[0]; // Check in each direction //left if (!AlreadyAdded(point.X - 1, point.Y, ref bmp) && IsBlack(point.X - 1, point.Y, ref bmp)) { alreadyAdded[point.X - 1, point.Y] = true; continguousEdges.Add(new Point(point.X - 1, point.Y)); pointAdded = true; } //right if (!AlreadyAdded(point.X + 1, point.Y, ref bmp) && IsBlack(point.X + 1, point.Y, ref bmp)) { alreadyAdded[point.X + 1, point.Y] = true; continguousEdges.Add(new Point(point.X + 1, point.Y)); pointAdded = true; } //Up if (!AlreadyAdded(point.X, point.Y - 1, ref bmp) && IsBlack(point.X, point.Y - 1, ref bmp)) { alreadyAdded[point.X, point.Y - 1] = true; continguousEdges.Add(new Point(point.X, point.Y - 1)); pointAdded = true; } //Down if (!AlreadyAdded(point.X, point.Y + 1, ref bmp) && IsBlack(point.X, point.Y + 1, ref bmp)) { alreadyAdded[point.X, point.Y + 1] = true; continguousEdges.Add(new Point(point.X, point.Y + 1)); pointAdded = true; } foreach (var pt in continguousEdges) { if ((pt.X == point.X) && (pt.Y == point.Y)) { continguousEdges.Remove(pt); break; } } } } for (int x = 0; x < bmp.Width; x++) { for (int y = 0; y < bmp.Height; y++) { if (alreadyAdded[x, y]) { isBlack[x, y] = true; } } } int xMiddle = bmp.Width / 2; // Find top of bottom border (we want to invert the bottom) int innerBottomBorder = bmp.Height; for (int y = bmp.Height - 1; y > bmp.Height / 2; y--) { if (isBlack[xMiddle, y]) { innerBottomBorder = y; } else { //break; } } int innerTopBorder = 0; for (int y = 1; y < bmp.Height / 2; y++) { if (isBlack[xMiddle, y]) { innerTopBorder = y; } else { //break; } } int innerLeft = 0; int innerRight = bmp.Width; // Find the inner-left and inner-right border for (int x = 2; x < bmp.Width / 2; x++) { if (isBlack[x, 25]) { innerLeft = x; } else { //break; } } // Find the inner-left and inner-right border for (int x = bmp.Width - 1; x > bmp.Width / 2; x--) { if (isBlack[x, 25]) { innerRight = x; } else { //break; } } System.Drawing.Color drawingColor = subColor; System.Drawing.Bitmap whitedOut = bmp; // Detect system cards and force a 15-pixel border if ((innerBottomBorder < bmp.Height - 1) && (innerTopBorder > 0) && (innerLeft > 0) && (innerRight < bmp.Width)) { int defaultBorder = 15; int maxBorder = 25; if ((innerBottomBorder < (bmp.Height - maxBorder)) || (innerTopBorder > maxBorder) || (innerLeft > maxBorder) || (innerRight < bmp.Width - maxBorder)) { // System card detected! Add 4 borders of 15 pixels each! innerBottomBorder = bmp.Height - defaultBorder; innerTopBorder = defaultBorder; innerLeft = defaultBorder; innerRight = bmp.Width - defaultBorder; } } // Invert the bottom-border and then sub-out all of the other pixels for (int x = 0; x < whitedOut.Width; x++) { for (int y = 0; y < whitedOut.Height; y++) { if (y >= innerBottomBorder) { Color oldPixel = whitedOut.GetPixel(x, y); whitedOut.SetPixel(x, y, Color.FromArgb(255 - oldPixel.R, 255 - oldPixel.G, 255 - oldPixel.B)); } if ((x <= innerLeft) || (x >= innerRight) || (y <= innerTopBorder) || (y >= innerBottomBorder)) { if (isBlack[x, y]) { whitedOut.SetPixel(x, y, drawingColor); } } } } // If not turning white, remove any white pixels if (subColor != System.Drawing.Color.White) { // Remove any white pixels for (int x = 0; x < whitedOut.Width; x++) { for (int y = 0; y < whitedOut.Height; y++) { if (y >= innerBottomBorder) { int whiteThreshold = 150; Color oldPixel = whitedOut.GetPixel(x, y); if ((oldPixel.R > whiteThreshold) && (oldPixel.G > whiteThreshold) && (oldPixel.B > whiteThreshold)) { whitedOut.SetPixel(x, y, drawingColor); } } } } } /* * // Draw a slight black border around the whole image for cutting purposes * for (int x = 0; x < whitedOut.Width; x++) * { * for (int y = 0; y < whitedOut.Height; y++) * { * if ((y == whitedOut.Height - 1) || (x == whitedOut.Width - 1) || * (y == 0) || (x == 0)) * { * whitedOut.SetPixel(x, y, Color.FromArgb(255, 200, 200, 200)); * } * } * } */ return(whitedOut); }