1

I have been working to create a freeform cropping tool using Unity's Texture2D class and the mask component. Till now I have created a system with which a user can draw a freeform shape on a transparent image. I need an algorithm with which I will be able to identify and fill the portion which is inside the drawn region.

Till now I have implemented the following approaches

  1. I used this logic to identify if a point was between the drawn shape but this doesn't work for freeform drawn shapes https://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/
int count;
        int a = 0;

        for (int x = 0; x < image_width; x++)
        {
            count = 0;
            for (int y = 0; y < image_height-1; y++)
            {
                if (drawingLayerTexture.GetPixel(x, y) == Color.red && drawingLayerTexture.GetPixel(x, y + 1) != Color.red)
                {
                    count++;
                }
            }

            if(drawingLayerTexture.GetPixel(x,image_height)==Color.red)
            {
                count++;
            }

            if (count > 1)
            {
                count = 0;
                for (int y = 0; y < image_height-1; y++)
                {
                    if (drawingLayerTexture.GetPixel(x, y) == Color.red && drawingLayerTexture.GetPixel(x, y + 1) != Color.red)
                    {
                        count++;
                    }
                    if (count % 2 == 1)
                    {
                        drawingLayerTexture.SetPixel(x, y, Color.white);
                        a++;
                    }
                }
            }
        }
  1. Instead of checking only for a line, I checked the point above and besides the point but it still doesn't work for all cases
// Red is the color of the freeform shape drawn by the user, White is the region which is inside the shape

for(int y=0;y<image_height;y++)
        {
            for(int x=0;x<image_width;x++)
            {
                if (drawingLayerTexture.GetPixel(x, y) == Color.red)
                    drawingLayerTexture.SetPixel(x, y, Color.white);
                else if (x == 0 || y == 0)
                    continue;
                else if ((drawingLayerTexture.GetPixel(x - 1, y) == Color.white) && (drawingLayerTexture.GetPixel(x, y - 1) == Color.white))
                    drawingLayerTexture.SetPixel(x, y, Color.white);
            }
        }

The shape drawn(in red lines)

The region identified(incorrect)

Even though I understand why each of these approaches doesn't work, I can't think of a correct algorithm

  • What is your required output image? – Rahul Kedia Jul 11 '20 at 12:56
  • The area drawn by the user(in red) must be filled with white color – Prathamesh Rajput Jul 11 '20 at 13:05
  • I had one more doubt, the leftmost verticle line of the red area is not completely red and the rightmost red area is broken. Do you want to join these broken areas with lines and then colour the inside area with white or anything else? Also, can the user not draw completely closed red curve? – Rahul Kedia Jul 11 '20 at 13:09
  • It is correct the screencap makes it look like that [here's](https://imgur.com/a/mOXFuzR) another zoomed in image of the user drawn area also the drawn area is always completely closed – Prathamesh Rajput Jul 11 '20 at 13:39
  • [Here](https://imgur.com/yxjqS28) is the cropping which happens on the drawn area – Prathamesh Rajput Jul 11 '20 at 13:50

1 Answers1

0

You could make a outline using a solid color (no anti-aliasing), then draw four imaginary lines outward from each pixel and only fill them in if all of them intersect with the outline. As far as I know it should always work on closed shapes. It's extremely inefficient, but it's a good start.

Rami
  • 1
  • 1
  • 1
  • https://www.reddit.com/r/GoForGold/comments/hq62va/go_for_gold_weekly_megathread_july_13_2020/fy88d34?utm_source=share&utm_medium=web2x – Prathamesh Rajput Jul 16 '20 at 06:33