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;
                    }
                }
            }
        }
Example #3
0
    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();
    }
Example #4
0
    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);
    }