
Region from BitmapA very common question is
"I have a bitmap that I want to extract a shape from and then use that
shape as the outline for a form. How can I get a region from a bitmap?" This is accomplished
using a simple raster scan analysis technique that scans an image line by line
and pixel by pixel in much the same way as a television picture is built up on
the screen. The interesting portions of the image are detected in some way and a
description of the area is retained for later use. In the case of a GDI+
Region object, the region of interest is described by an array of rectangles
that tile to cover the area of the inside of the region. A simple program
can be used to get a bunch of individual rectangles which are then combined with
the original empty region object to create the mask for your image. There are several
techniques that can be used to extract this information including quite complex
analysis of pixel colour or brightness but the simplest and most commonly used
is to physically paint over the bits of the image that you don't want and allow
the analysis program to give you rectangles that cover the rest. In this example, I have
taken an image, painted the bits I don’t need with some garish color not found
in the original, in this case pure magenta, and then subjected the resulting
image to analysis. Figure 1 shows the
original and treated image for comparison.
Figure
1: The original and treated image When loaded into memory,
the bitmap can be analysed with the simple routine shown in listing 1. private
Region GetRegion(Bitmap _img, Color color) { Color _matchColor=Color.FromArgb(color.R,color.G,color.B); System.Drawing.Region rgn= new
Region(); rgn.MakeEmpty(); Rectangle rc=new
Rectangle(0,0,0,0); bool
inimage=false; for(int
y=0; y<_img.Height;y++) { for(int
x=0;x<_img.Width;x++) {
if(!inimage)
{
if(_img.GetPixel(x,y)!=_matchColor)
{
inimage=true;
rc.X=x;
rc.Y=y;
rc.Height=1;
}
}
else
{
if(_img.GetPixel(x,y)==_matchColor)
{
inimage=false;
rc.Width=x-rc.X;
rgn.Union(rc);
}
}
} if(inimage) {
inimage=false;
rc.Width=_img.Width-rc.X;
rgn.Union(rc); } } return rgn; } The resulting region can
be used to crop the original image, keeping only the bits not painted in by
hand. To accompany this article
I have prepared a C# application that uses this technique to create a form the
same shape as the bike in the picture. The outline of the region is also filled
with color to illustrate its use as a graphics clipping region. Figure 2 shows
this application in action. You can download
this application from here.
Figure
2: A floating form shaped like a Triumph Bonneville and its outline used as a
mask |