abenci
abenci

Reputation: 8681

How do I read pixels inside a closed polygon?

Which is the best approach for reading the color of bitmap pixels inside a closed polygon?

The closed polygon is defined as a list of System.Drawing.Point in the bitmap dimensions. I am using C# and .NET Framework.

Thanks.

Upvotes: 2

Views: 1650

Answers (3)

Tomaz Stih
Tomaz Stih

Reputation: 579

Very interesting topic. Reducing your rectangle as proposed by Kogitsune sounds like a rational first step. But I think you don't need a region for that. If you simply find the largest and smallest x and y coordinates of all your points, you will have your smallest rectangle that still contains the whole polygon. You can then try using efficient polygon fill algorithm to find all horizontal lines within your polygon. And then simply calc. color of these.

Upvotes: 0

Kogitsune
Kogitsune

Reputation: 415

A possible way would be to create an instance of Drawing2D.GraphicsPath and add your points via GraphicsPath.AddLines( PointF[] ), then create a region using the GraphicsPath as an argument to your constructor.

Then, you perform a hit test based on the smallest rectangle your polygon fits in using Region.IsVisible( x, y, graphicsobject ).

This method would be somewhat more efficient than creating a second bitmap, but might not be as fast.

This is VB, but is easily translatable:

Dim path As New GraphicsPath

path.AddLines( YourPointsArray )

path.CloseFigure( )

Dim rgn As New Region( path )

'Find your min/max box based on YourPointsArray here

For y As Integer = min.Y To max.Y
  For x as Integer = min.X To max.X
    If rgn.IsVisible( x, y, YourGraphicsObject ) Then
      'Do what you need to do
    End If
  Next
Next

It is just quick example code, but should get the idea across.

Upvotes: 0

C.Evenhuis
C.Evenhuis

Reputation: 26446

As far as I know c# does not provide this functionality by default. The easiest way perhaps is to create a second image with a white background, where you FillPolygon the polygon with black pixels. Then you scan the entire second image for black pixels, and read each black pixel from the original image at the same coordinate.

This will of course be slow if the polygon is a small part of a large image, but you can easily determine the bounds in which the polygon falls and only create a map for that area.

Another way is scan a line from (-1, 0) to (width + 1, 0) and calculate the intersections with each polygon line, after an intersection the next pixels are inside the polygon, and after the next intersection the pixels are outside. Then scan (-1, 1) to (width + 1, 1) etc. Keep in mind that a line intersecting with a point exactly matching a polygon point should take extra care.

Upvotes: 1

Related Questions