FillBitmap Method
The FillBitmap method applies a specified replacement color to those pixels that either match the color of a specified "seed" pixel or fall within a color-defined boundary. The color change may be restricted further to only those neighboring pixels that directly or indirectly match the seed pixel.
The seed pixel is specified by its x and y offset from the top-left corner of the bitmap.
This method replaces pixels based on matching color, where a match is when the color falls within a defined range of the color of the seed pixel. If a boundary fill is specified, only non-matching pixels are recolored. Otherwise, only matching pixels are recolored.
You can specify the replacement color directly as an RGB value or from the corresponding pixel from a 'replacement' bitmap. The replacement bitmap must be at least the size of the bitmap being recolored.
Neighbor-based filling is achieved through a cascading fill (sometimes known as flood-fill) that starts from the seed pixel and replaces all matching perpendicularly-adjacent pixels outwardly; after this primary replacement, the technique then applies the same process to the pixels neighboring these primaries, and so on, until there are no more matches. This is the default behavior.
Boundary filling recolors outward from (and including) the seed pixel until it encounters pixels that match the specified replacement color, which it treats as boundary pixels.
"All" fill recolors every matching pixel in the bitmap, no matter where it appears.
If the BitmapObject is attached to a FormField or a stored TaggedValue Item, using this in your program during development may change your frame's source definition. See BitmapObject Attributes and Methods Affecting the Frame Source (see
BitmapObject Class).
This method has the following syntax:
Status = BitmapObject.FillBitmap(replacementcolor = integer | replacementbitmap = BitmapObject
[, x = integer, y = integer][, range = integer][, all = integer]
[, boundary = integer][, bounds = integer])
This method has the following parameters:
replacementcolor
Specifies the color to apply to pixels identified for recoloring. This parameter is ignored if replacementbitmap is specified.
Default: Black, RGB(0,0,0)
replacementbitmap
Specifies the bitmap whose corresponding pixels supply the color to be used to recolor designated pixels.
Default: NULL
x
Specifies the x location of the seed pixel on the bitmap.
y
Specifies the y location of the seed pixel on the bitmap.
range
Specifies the range of color that will be treated as a match. The range is specified as a percentage:
• 0 or 1 specifies that only the exact color should be replaced.
• 10 specifies replacement of any color whose individual red green and blue values are within 5% of either side of the exact color's red green and blue values (10 = -5% to +5%).
• 50 specifies replacement within 25% of either side.
• 100 specifies replacement within 50% of either side.
• 200 guarantees replacement of 100% of either side.
all
Specifies whether to replace all matching pixels rather than only contiguous ones. If boundary is TRUE, this parameter is ignored.
Default: FALSE
boundary
Specifies whether to replace color based on a color-matched boundary.
Default: FALSE
bounds
Contains the x,y coordinates (as pixel positions) defining the limit (boundary) of the fill area, for flood fill and boundary fill.
The method returns ER_OK if successful. The bitmap object's errorstatus is also set to the return value.
This method relies on the color of the seed pixel to determine which pixels to replace. Where "all" is specified (recolor all pixels that match the specified replacementcolor), the location of a matching pixel to use as a seed pixel may be unknown. In such a case, temporarily recoloring the top-left pixel can resolve this problem. For example, to replace all yellow pixels with green ones, you could use the following code:
topleftcolor = bitmap.GetPixelColor(x=1, y=1);
bitmap.SetPixelColor(x=1, y=1, color=RGB(red=255, green=255, blue=0));
bitmap.FillBitmap(x=1, y=1, replacementcolor=RGB(red=0, green=255, blue=0), all=TRUE);
bitmap.SetPixelColor(x=1, y=1, color=topleftcolor);
Boundary fill uses the specified replacementcolor both as fill color and as a boundary identifier. Therefore, a boundary fill with range 0 will fill the whole area that includes the seed pixel with the boundary color; subsequent fill recoloring of this area will recolor the boundary itself.
If you need to recolor the area to a non-boundary color while preserving the boundary, use the following approach:
1. Set the range to 2.
2. Specify a fill color adjacent to (within the range of) the boundary color.
3. Apply the boundary fill.
4. Then apply a flood fill with your color of choice.
Now the boundary color is distinct from the fill color, and you can recolor the area without changing the boundary. For example, given a circular boundary of pure black, RGB(0,0,0), that you want to preserve while the exterior is recolored to blue, you could achieve this with the following code:
bitmap.FillBitmap(x=1, y=1, color=1, range=2, boundary=TRUE); //boundary color 0, fill color 1
bitmap.FillBitmap(x=1, y=1, color=RGB(red=0, green=0, blue=255)); //replaces all color 1 pixels
The bounds parameter is meant for use with the
ReplaceBitmap Method, whose coordinates parameter accepts a LongByteObject of x,y data formatted in this way and applies it as a constraint on the area to be replaced. This enables irregularly shaped areas to be defined and subsequently replaced.
Consider the following example. We have:
• A bitmap of a map outlining the counties in a state or country
• The same map without the outlines, displayed in an image field whose bias is FB_CLICKPOINT
• The same map without the outlines, showing the satellite image (or other social, geographic, or economic details) of that state or country
The following code obtains the coordinates of the pixels bounding the county which a user clicked:
On ChildClickpoint =
{
x = (curframe.XStart*96)/1000; //96 pixels to an inch on standard displays
y = (curframe.YStart*96)/1000;
mymap = myOutlineMap.Duplicate(); //duplicate to preserve the original map
mymap.FillBitmap(
x=x, y=y,
range=80, //use highest range that excludes the border color
bounds=Byref(myLongByteCoords));
}
The following code fills that clicked county, and only that county, with the satellite details:
mymap = field(myEmptyMap).Image;
mymap.ReplaceBitmap(
replacement=mySatelliteMap,
coordinates=myLongByteCoords);
If the displayed bitmap was the outline map, the initial FillBitmap call could have included:
replacement=myDetailedMap,
This would display the county details at once, but with the county border outlines included.