Exemple #1
0
 //Draws a border on the bitmap
 public static PixelMatrix Border(PixelMatrix bitmap, Color color)
 {
     for (int i = 0; i < bitmap.height; i++)
     {
         bitmap.SetPixelSafe(0, i, color);
         bitmap.SetPixelSafe(bitmap.width - 1, i, color);
     }
     for (int i = 0; i < bitmap.width; i++)
     {
         bitmap.SetPixelSafe(i, 0, color);
         bitmap.SetPixelSafe(i, bitmap.height - 1, color);
     }
     return(bitmap);
 }
Exemple #2
0
    //Rotate an image by increments of 90 degrees
    public static PixelMatrix RotateSq(PixelMatrix original, int rotates)
    {
        //No more rotates
        if (rotates == 0)
        {
            return(original);
        }

        //Setup new rotated
        int         side    = Mathf.Max(original.width, original.height);
        PixelMatrix rotated = new PixelMatrix(side, side, Color.clear);

        //Rotate 90º
        for (int i = 0; i < original.width; i++)
        {
            int finalI = original.width - i - 1;
            for (int j = 0; j < original.height; j++)
            {
                rotated.SetPixelSafe(j, finalI, original.GetPixelSafe(i, j));
            }
        }

        //Call new rotation
        rotated = RotateSq(rotated, rotates - 1);

        return(rotated);
    }
Exemple #3
0
    //Scan-line flood fill, much faster
    //https://lodev.org/cgtutor/floodfill.html#Scanline_Floodfill_Algorithm_With_Stack
    public static PixelMatrix FloodFillLine(PixelMatrix bmp, int x, int y, Color replacementColor)
    {
        Point pt = new Point(x, y);

        Color targetColor = bmp.GetPixel(pt.x, pt.y);

        if (targetColor == replacementColor)
        {
            return(bmp);
        }

        Stack <Point> pixels = new Stack <Point>();

        pixels.Push(pt);
        while (pixels.Count != 0)
        {
            Point temp = pixels.Pop();
            int   y1   = temp.y;

            while (y1 >= 0 && bmp.GetPixel(temp.x, y1) == targetColor)
            {
                y1--;
            }
            y1++;
            bool spanLeft  = false;
            bool spanRight = false;

            while (y1 < bmp.height && bmp.GetPixel(temp.x, y1) == targetColor)
            {
                bmp.SetPixelSafe(temp.x, y1, replacementColor);

                Color clm1 = bmp.GetPixel(temp.x - 1, y1);
                Color clp1 = bmp.GetPixel(temp.x + 1, y1);

                if (!spanLeft && temp.x > 0 && clm1 == targetColor)
                {
                    pixels.Push(new Point(temp.x - 1, y1));
                    spanLeft = true;
                }
                else if (spanLeft && temp.x - 1 >= 0 && clm1 != targetColor)
                {
                    spanLeft = false;
                }
                if (!spanRight && temp.x < bmp.width - 1 && clp1 == targetColor)
                {
                    pixels.Push(new Point(temp.x + 1, y1));
                    spanRight = true;
                }
                else if (spanRight && temp.x < bmp.width - 1 && clp1 != targetColor)
                {
                    spanRight = false;
                }
                y1++;
            }
        }

        return(bmp);
    }
Exemple #4
0
    //Fill Polygon
    //Looks much faster and quite promissing
    //http://alienryderflex.com/polygon_fill/
    public static PixelMatrix FillPolygon(PixelMatrix original, List <Geometry.Vector2X> polygon, Color cl)
    {
        int pixelX, pixelY, swap;
        int i, j, nodes;

        int[] nodeX = new int[polygon.Count];

        //Limits of polygon
        int IMAGE_TOP = original.height + 1, IMAGE_BOT = -1, IMAGE_RIGHT = -1, IMAGE_LEFT = original.width + 1;

        for (int p = 0; p < polygon.Count; p++)
        {
            if (polygon[p].value.x > IMAGE_RIGHT)
            {
                IMAGE_RIGHT = (int)polygon[p].value.x;
            }
            else if (polygon[p].value.x < IMAGE_LEFT)
            {
                IMAGE_LEFT = (int)polygon[p].value.x;
            }
            if (polygon[p].value.y < IMAGE_TOP)
            {
                IMAGE_TOP = (int)polygon[p].value.y;
            }
            else if (polygon[p].value.y > IMAGE_BOT)
            {
                IMAGE_BOT = (int)polygon[p].value.y;
            }
        }

        //  Loop through the rows of the image.
        for (pixelY = IMAGE_TOP; pixelY < IMAGE_BOT; pixelY++)
        {
            //  Build a list of nodes.
            nodes = 0; j = polygon.Count - 1;
            for (i = 0; i < polygon.Count; i++)
            {
                if (polygon[i].value.y < pixelY && polygon[j].value.y >= pixelY || polygon[j].value.y < pixelY && polygon[i].value.y >= pixelY)
                {
                    nodeX[nodes++] = (int)(polygon[i].value.x + (pixelY - polygon[i].value.y) / (polygon[j].value.y - polygon[i].value.y) * (polygon[j].value.x - polygon[i].value.x));
                }
                j = i;
            }

            //  Sort the nodes, via a simple “Bubble” sort.
            i = 0;
            while (i < nodes - 1)
            {
                if (nodeX[i] > nodeX[i + 1])
                {
                    swap         = nodeX[i];
                    nodeX[i]     = nodeX[i + 1];
                    nodeX[i + 1] = swap;
                    if (i != 0)
                    {
                        i--;
                    }
                }
                else
                {
                    i++;
                }
            }

            //  Fill the pixels between node pairs.
            for (i = 0; i < nodes; i += 2)
            {
                if (nodeX[i] >= IMAGE_RIGHT)
                {
                    break;
                }
                if (nodeX[i + 1] > IMAGE_LEFT)
                {
                    if (nodeX[i] < IMAGE_LEFT)
                    {
                        nodeX[i] = IMAGE_LEFT;
                    }
                    if (nodeX[i + 1] > IMAGE_RIGHT)
                    {
                        nodeX[i + 1] = IMAGE_RIGHT;
                    }
                    for (pixelX = nodeX[i]; pixelX < nodeX[i + 1]; pixelX++)
                    {
                        original.SetPixelSafe(pixelX, pixelY, cl);
                    }
                }
            }
        }

        return(original);
    }