filling shapes with patterns in CImg
I want to be able to draw shapes and flood-fill them with various fill patterns (diagonal lines, stipple dots, etc).
The CImg library includes function开发者_StackOverflow中文版s for drawing various shapes with an arbitrary line pattern for the outline. But I don't see anything about fill pattern.
I think this can probably be done using a bitwise or mathematical operator to mask the pattern onto a solid image, but I'd like to see the specific code for doing it.
Yes, polygon fill patterns can be achieved by first drawing the polygon in a solid color and then using the &= operator with a pre-loaded black-and-white pattern image.
// preload several pattern images (black and white versions of the desired fill patterns)
CImg<unsigned char> *fillPatternImages[ NumFillPatterns ] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
fillPatternImages[ 0 ] = new CImg<unsigned char>( "256x256_bw_dotted_fill.png" );
... etc. for all patterns you want to use
// create an empty image
CImg<unsigned char> image( 256, 256, 1, 4, 0 );
// draw the polygon (or in the case of my code, any number of polygons) on the image in a solid color
if ( nShapeType == SHPT_POLYGON && fillPattern != FILL_PATTERN_NONE )
{
for( int i = 0 ; i < nShapeCount ; i++ )
{
SHPObject *psShape;
psShape = SHPReadObject( hSHP, panHits[ i ] );
for ( int part = 0 ; part < psShape->nParts ; part++ )
{
int numPoints;
if ( part < ( psShape->nParts - 1 ) )
{
numPoints = psShape->panPartStart[ part + 1 ] - psShape->panPartStart[ part ];
}
else
{
numPoints = psShape->nVertices - psShape->panPartStart[ part ];
}
CImg<int> pointImage( numPoints, 2, 1, 1, 0 );
int s = psShape->panPartStart[ part ];
for ( int p = 0 ; p < numPoints ; p++ )
{
int screenX;
int screenY;
GetTileXYFromMercatorLonLat( (float)psShape->padfX[ s + p ], (float)psShape->padfY[ s + p ], x, y, z, &screenX, &screenY );
pointImage( p, 0 ) = screenX;
pointImage( p, 1 ) = screenY;
}
image.draw_polygon( pointImage, fillColor );
}
SHPDestroyObject( psShape );
}
}
// to achieve a non-solid pattern, & the image with a pre-loaded pattern image
if ( fillPattern > -1 )
{
image &= *fillPatternImages[ fillPattern ];
}
精彩评论