public static TextureBitmap GetBitmap(this DesignPattern pattern) { int width = pattern.Width; int height = pattern.Height; var bitmap = new TextureBitmap(width, height); unsafe { TextureBitmap.Color *ptr = bitmap.GetColors(); for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var b = pattern.GetPixel(x, y); if (b == 15) { *(ptr + x + (height - 1 - y) * width) = new TextureBitmap.Color(0, 0, 0, 0); } else { var c = pattern.Palette[b]; *(ptr + x + (height - 1 - y) * width) = new TextureBitmap.Color(c.R, c.G, c.B, 255); } } } } return(bitmap); }
private static void CalculateLuminanceValues32BitWithAlpha(TextureBitmap bitmap, byte[] luminances) { var height = bitmap.Height; var width = bitmap.Width; var pixelWidth = bitmap.PixelSize; var maxIndex = 4 * width; unsafe { var ptr = bitmap.GetColors(); for (int y = 0; y < height; y++) { var offset = y * width; for (int x = 0; x < width; x++) { var col = *(ptr + x + (height - 1 - y) * width); var luminance = (byte)((BChannelWeight * (col).B + GChannelWeight * (col).G + RChannelWeight * (col).R) >> ChannelWeight); var alpha = col.A; luminance = (byte)(((luminance * alpha) >> 8) + (255 * (255 - alpha) >> 8) + 1); luminances[x + y * width] = luminance; } } } }
public void Clear() { var p = new SimpleDesignPattern(); p.Type = this.Type; //p.IsPro = this.Type != DesignPattern.TypeEnum.SimplePattern; p.Image = new byte[p.Width / 2 * p.Height]; p.Empty(); var colors = p.GetPixels(); unsafe { var bitmapColors = Bitmap.GetColors(); for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { var col = new TextureBitmap.Color( (byte)(colors[x + y * Width].r * 255f), (byte)(colors[x + y * Width].g * 255f), (byte)(colors[x + y * Width].b * 255f), (byte)(colors[x + y * Width].a * 255f) ); *(bitmapColors + x + y * Width) = col; } } } Load(); }
public Pattern(PatternEditor editor, DesignPattern pattern) { try { Logger.Log(Logger.Level.INFO, "[PatternEditor/Pattern] Creating new pattern"); StartPreviewThread(); Logger.Log(Logger.Level.DEBUG, "[PatternEditor/Pattern] Preview generator thread started!"); _Type = pattern.Type; Logger.Log(Logger.Level.DEBUG, "[PatternEditor/Pattern] Pattern type: " + _Type.ToString()); Bitmap = new TextureBitmap(pattern.Width, pattern.Height); Logger.Log(Logger.Level.DEBUG, "[PatternEditor/Pattern] Created TextureBitmap " + pattern.Width + "x" + pattern.Height); Bitmap.Clear(); PreviewBitmap = new TextureBitmap(pattern.Width, pattern.Height); Logger.Log(Logger.Level.DEBUG, "[PatternEditor/Pattern] Created preview TextureBitmap " + pattern.Width + "x" + pattern.Height); PreviewBitmap.Clear(); PreviewSprite = UnityEngine.Sprite.Create(PreviewBitmap.Texture, new UnityEngine.Rect(0, 0, PreviewBitmap.Width, PreviewBitmap.Height), new UnityEngine.Vector2(0.5f, 0.5f)); Logger.Log(Logger.Level.DEBUG, "[PatternEditor/Pattern] Created preview sprite"); UpscaledPreviewBitmap = new TextureBitmap(pattern.Width * 4, pattern.Height * 4); Logger.Log(Logger.Level.DEBUG, "[PatternEditor/Pattern] Created upscaled preview TextureBitmap " + (pattern.Width * 4) + "x" + (pattern.Height * 4)); UpscaledPreviewBitmap.Clear(); Quantizer = Quantizers[0]; Logger.Log(Logger.Level.DEBUG, "[PatternEditor/Pattern] Selected Quantizer: " + Quantizer.GetType().ToString()); ColorCache = ColorCaches[0]; Logger.Log(Logger.Level.DEBUG, "[PatternEditor/Pattern] Selected Color Cache: " + ColorCache.GetType().ToString()); Editor = editor; DesignPattern = pattern; var colors = pattern.GetPixels(); Logger.Log(Logger.Level.DEBUG, "[PatternEditor/Pattern] Parsing colors of pattern..."); unsafe { var bitmapColors = Bitmap.GetColors(); for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { var col = new TextureBitmap.Color( (byte)(colors[x + y * Width].r * 255f), (byte)(colors[x + y * Width].g * 255f), (byte)(colors[x + y * Width].b * 255f), (byte)(colors[x + y * Width].a * 255f) ); *(bitmapColors + x + (Height - 1 - y) * Width) = col; } } } Logger.Log(Logger.Level.DEBUG, "[PatternEditor/Pattern] Parsed " + (Width * Height) + " pixels."); Info = DesignPatternInformation.Types[pattern.Type]; Logger.Log(Logger.Level.DEBUG, "[PatternEditor/Pattern] Pattern information obtained."); } catch (System.Exception e) { Logger.Log(Logger.Level.ERROR, "[PatternEditor/Pattern] Error while creating pattern: " + e.ToString()); } }
public static void FromBitmap(this DesignPattern pattern, TextureBitmap bitmap) { Dictionary <TextureBitmap.Color, byte> colorMap = new Dictionary <TextureBitmap.Color, byte>(); for (int i = 0; i < 15; i++) { pattern.Palette[i].R = 0; pattern.Palette[i].G = 0; pattern.Palette[i].B = 0; } int width = pattern.Width; int height = pattern.Height; unsafe { var colors = bitmap.GetColors(); pattern.Image = new byte[width * height]; int bitmapHeight = bitmap.Height; int bitmapWidth = bitmap.Width; for (var y = 0; y < width; y++) { for (var x = 0; x < height; x++) { var pixelColor = new TextureBitmap.Color(0, 0, 0, 0); if (x < bitmapWidth && y < bitmapHeight) { pixelColor = colors[x + (bitmapHeight - 1 - y) * bitmapHeight]; } byte index = 0xF; if (pixelColor.A == 255) { if (colorMap.ContainsKey(pixelColor)) { index = colorMap[pixelColor]; } else { index = (byte)colorMap.Count; pattern.Palette[index].R = pixelColor.R; pattern.Palette[index].G = pixelColor.G; pattern.Palette[index].B = pixelColor.B; colorMap.Add(pixelColor, index); } } pattern.SetPixel(x, y, index); } } } }
public static (int, int, int, int) FindPattern(TextureBitmap bitmap, DesignPattern.TypeEnum type) { bool isPro = type != DesignPattern.TypeEnum.SimplePattern; unsafe { var colors = bitmap.GetColors(); int bitmapWidth = bitmap.Width; int bitmapHeight = bitmap.Height; bool[] bw = new bool[bitmapWidth * bitmapHeight]; // true = black int min = 180; int max = 235; for (int x = 0; x < bitmapWidth; x++) { for (int y = 0; y < bitmapHeight; y++) { float h; float s; float v; var col = colors[x + y * bitmapWidth]; int r = (int)(col.R); int g = (int)(col.G); int b = (int)(col.B); r = r * (r >= min && r <= max ? 0 : 1); g = g * (g >= min && g <= max ? 0 : 1); b = b * (b >= min && b <= max ? 0 : 1); bw[x + y * bitmapWidth] = r == 0 && g == 0; } } int widthThreshold = 5; int minWidth = 2; List <(int, int, int)> horizontalLines = new List <(int, int, int)>(); List <(int, int, int)> verticalLines = new List <(int, int, int)>(); for (int y = 0; y < bitmapHeight; y++) { int currentDashWidth = 0; int currentSpaceWidth = 0; int dashes = 0; int dashWidth = 0; int start = 0; bool black = false; for (int x = 0; x < bitmapWidth; x++) { int idx = x + y * bitmapWidth; if (bw[idx]) { if (!black) { currentDashWidth = 0; if (dashes > 0 && currentSpaceWidth > dashWidth) { dashes = 0; dashWidth = 0; } if (dashes == 0) { start = x; } } black = true; currentDashWidth++; } else { if (dashes == 0 && currentDashWidth >= minWidth) { dashWidth = currentDashWidth; } if (dashWidth > 0) { if (black) { currentSpaceWidth = 0; if (currentDashWidth < dashWidth - widthThreshold || currentDashWidth < minWidth || currentDashWidth > dashWidth + widthThreshold) { dashes = 0; dashWidth = 0; } else { dashes++; if (dashes >= 14) { horizontalLines.Add((start, y, x)); dashWidth = 0; dashes = 0; continue; } } } if (dashes > 0) { currentSpaceWidth++; } } black = false; } } } for (int x = 0; x < bitmapWidth; x++) { int currentDashWidth = 0; int currentSpaceWidth = 0; int dashes = 0; int dashWidth = 0; int start = 0; bool black = false; for (int y = 0; y < bitmapHeight; y++) { int idx = x + y * bitmapWidth; if (bw[idx]) { if (!black) { currentDashWidth = 0; if (dashes > 0 && currentSpaceWidth > dashWidth) { dashes = 0; dashWidth = 0; } if (dashes == 0) { start = y; } } black = true; currentDashWidth++; } else { if (dashes == 0 && currentDashWidth >= minWidth) { dashWidth = currentDashWidth; } if (dashWidth > 0) { if (black) { currentSpaceWidth = 0; if (currentDashWidth < dashWidth - widthThreshold || currentDashWidth < minWidth || currentDashWidth > dashWidth + widthThreshold) { dashes = 0; dashWidth = 0; } else { dashes++; if (dashes >= 14) { verticalLines.Add((x, start, y)); dashWidth = 0; dashes = 0; continue; } } } if (dashes > 0) { currentSpaceWidth++; } } black = false; } } } int sizeThreshold = 10; // find pairing horizontal lines List <List <int> > horizontalGroups = new List <List <int> >(); List <int> foundHorizontal = new List <int>(); for (int i = 0; i < horizontalLines.Count - 1; i++) { if (!foundHorizontal.Contains(i)) { List <int> group = new List <int>(); group.Add(i); for (int j = i + 1; j < horizontalLines.Count; j++) { if (UnityEngine.Mathf.Abs(horizontalLines[i].Item1 - horizontalLines[j].Item1) < sizeThreshold && UnityEngine.Mathf.Abs(horizontalLines[i].Item3 - horizontalLines[j].Item3) < sizeThreshold) { group.Add(j); foundHorizontal.Add(j); } } horizontalGroups.Add(group); } } // find pairing vertical lines List <List <int> > verticalGroups = new List <List <int> >(); List <int> foundVertical = new List <int>(); for (int i = 0; i < verticalLines.Count - 1; i++) { if (!foundVertical.Contains(i)) { List <int> group = new List <int>(); group.Add(i); for (int j = i + 1; j < verticalLines.Count; j++) { if (UnityEngine.Mathf.Abs(verticalLines[i].Item2 - verticalLines[j].Item2) < sizeThreshold && UnityEngine.Mathf.Abs(verticalLines[i].Item3 - verticalLines[j].Item3) < sizeThreshold) { group.Add(j); foundVertical.Add(j); } } verticalGroups.Add(group); } } (int, int)whiteR = (235, 255); (int, int)whiteG = (235, 255); (int, int)whiteB = (200, 255); List <(int, int, int, int, bool[])> rects = new List <(int, int, int, int, bool[])>(); for (int i = 0; i < verticalGroups.Count; i++) { var vTop = verticalLines[verticalGroups[i][0]].Item2; var vBottom = verticalLines[verticalGroups[i][0]].Item3; var vX = verticalLines[verticalGroups[i][0]].Item1; for (int j = 0; j < horizontalGroups.Count; j++) { var hLeft = horizontalLines[horizontalGroups[j][0]].Item1; var hRight = horizontalLines[horizontalGroups[j][0]].Item3; var hY = horizontalLines[horizontalGroups[j][0]].Item2; UnityEngine.Debug.Log(vTop + "-" + vBottom + "(" + vX + ") " + hLeft + "-" + hRight + "(" + hY + ")"); if ((UnityEngine.Mathf.Abs(hY - vTop) < sizeThreshold || UnityEngine.Mathf.Abs(hY - vBottom) < sizeThreshold) && (UnityEngine.Mathf.Abs(vX - hLeft) < sizeThreshold || UnityEngine.Mathf.Abs(vX - hRight) < sizeThreshold)) { // its a rect! int w = hRight - hLeft; int h = vBottom - vTop; bool[] rect = new bool[w * h]; // find outer top int outerTop = -1; for (int y = -30; y < 0; y++) { int r = (int)(colors[(hLeft + w / 2) + (vTop + y) * bitmapWidth].R); int g = (int)(colors[(hLeft + w / 2) + (vTop + y) * bitmapWidth].G); int b = (int)(colors[(hLeft + w / 2) + (vTop + y) * bitmapWidth].B); if (r >= 240 && g >= 240 && b >= 220) { outerTop = vTop + y; break; } } // find outer left int outerLeft = -1; for (int x = -30; x < 0; x++) { int r = (int)(colors[(hLeft + x) + (vTop + h / 2) * bitmapWidth].R); int g = (int)(colors[(hLeft + x) + (vTop + h / 2) * bitmapWidth].G); int b = (int)(colors[(hLeft + x) + (vTop + h / 2) * bitmapWidth].B); if (r >= 240 && g >= 240 && b >= 220) { outerLeft = hLeft + x; break; } } // find outer bottom int outerBottom = -1; for (int y = 29; y >= 0; y--) { int r = (int)(colors[(hLeft + w / 2) + (vBottom + y) * bitmapWidth].R); int g = (int)(colors[(hLeft + w / 2) + (vBottom + y) * bitmapWidth].G); int b = (int)(colors[(hLeft + w / 2) + (vBottom + y) * bitmapWidth].B); if (r >= 240 && g >= 240 && b >= 220) { outerBottom = vBottom + y + 1; break; } } // find outer right int outerRight = -1; for (int x = 29; x >= 0; x--) { int r = (int)(colors[(hRight + x) + (vTop + h / 2) * bitmapWidth].R); int g = (int)(colors[(hRight + x) + (vTop + h / 2) * bitmapWidth].G); int b = (int)(colors[(hRight + x) + (vTop + h / 2) * bitmapWidth].B); if (r >= 240 && g >= 240 && b >= 220) { outerRight = hRight + x + 1; break; } } UnityEngine.Debug.LogError(outerLeft + "," + outerTop + " (" + (outerBottom - outerTop) + "x" + (outerRight - outerLeft) + ")"); if (outerRight == -1 || outerLeft == -1 || outerTop == -1 || outerBottom == -1) { return(-1, -1, -1, -1); } int padding = UnityEngine.Mathf.CeilToInt(((float)(outerRight - outerLeft)) * 0.090f); int realLeft = outerLeft + padding; int realRight = outerRight - (padding - 1); int realTop = outerTop + padding; int realBottom = outerBottom - (padding - 1); return(realLeft, realTop, realRight - realLeft, realBottom - realTop); } } } } return(-1, -1, -1, -1); }