Click here to Skip to main content
13,801,559 members
Click here to Skip to main content
Add your own
alternative version

Tagged as


5 bookmarked
Posted 20 Jun 2014
Licenced CPOL

Applying Matrix Transformations in GDI+

, 20 Jun 2014
Rate this:
Please Sign up or sign in to vote.
Steps to implement the “Fit picture to fill the shape” option in PowerPoint like applications using GDI+


While working on an application which used GDI+ to draw advanced graphics, I came across a requirement to draw shapes like ellipse, square, triangle, arrow, etc. and fill it with image selected by the user.


This feature is similar to that available in Microsoft PowerPoint where the user is provided two options as follows:

  1. Tile picture as Texture: In this option, the image selected by the user is tiled inside the shape.

  2. Fit picture to fill the Shape: In this option, the image selected by the user is drawn inside the shape such that the image is properly spread across the shape. Tiling will not occur even after the size of the shape is increased or decreased.

We would be looking at the Fit picture to fill the shape option in depth in this blog as this mode poses a typical challenge when we fill any shape using Image Texture brush.

Windows GDI + provides us the facility to create a Texture brush (WrapModeClamp option) and then use it to draw inside the shape selected by the user.

Steps to Implement the “Fit Picture to Fill the Shape” option

  1. Load the image that you want to fill inside the shape:
    Image image(L"C:\\Users\\Public\\Pictures\\Sample Pictures\\Tulips.jpg");
    Image* ptrImagePoly = (Image*)&bmpInMemoryPoly;
    Graphics graphicsInMemoryPoly(ptrImagePoly );
  2. While creating the Texture brush, specify the image for the brush:
    TextureBrush tBrushPoly(ptrImagePoly );
  3. Then specify the wrap mode Clamp (fit to shape) in the texture brush:
    tBrushPoly.SetWrapMode( WrapModeClamp );
  4. Create the matrix object and set the proper relative translation (see Code Listing 2 and 3 below):
    Matrix X1;
    X1.Translate( 247, 100 );
  5. Set the matrix translation to the texture brush so that the brush draws the image at the proper location. If this is not done, then by default the brush draws the image at 0, 0 location and the image will not be properly filled in the shape.
    // Set the translation to the image brush rect 

Code listing 1: Basic GDI code setup to draw any annotations:

CPaintDC dc(this);
Graphics graphics(dc.m_hDC);
Image image(L"C:\\Users\\Public\\Pictures\\Sample Pictures\\Tulips.jpg");
Pen blackPen(Color(255, 255, 0, 0));
graphics.SetInterpolationMode( InterpolationModeHighQuality );

Code listing 2: Draw a square and fill it with an Image:

Bitmap bmpInMemoryRect( 200, 200 );
Image* ptrRect = (Image*)&bmpInMemoryRect;
Graphics graphicsInMemoryRect( ptrRect );
// Set translation according to the top-left tip of the Square shape.
// This moves the origin to 20, 20.
Matrix X2;
X2.Translate( 20, 20 );
graphicsInMemoryRect.DrawImage( &image, 0, 0, 200, 200 );
TextureBrush tBrushRect( ptrRect );
// Set the translation to the image brush rect
tBrushRect.SetWrapMode( WrapModeClamp );
graphics.DrawRectangle( &blackPen, Rect(20, 20, 200, 200) ); 
graphics.FillRectangle( &tBrushRect, Rect(20, 20, 200, 200) );

Code listing 3: Draw an arrow and fill it with an image:

Point * points; 
int iPointCount = 7; 
points = new Point[iPointCount]; 
// point[6]
// /\
// point[5] / \ point[0]
// - - 
// point[4] || point[3]
// point[4] ||
// point[2] -- point[1]
points[0].X = (int)406.78; 
points[0].Y = (int)220.11; 
points[1].X = (int)367.04; 
points[1].Y = (int)220.11; 

points[2].X = (int)367.04; 
points[2].Y = (int)321.66;
points[3].X = (int)287.57;
points[3].Y = (int)321.66; 

points[4].X = (int)287.57; 
points[4].Y = (int)220.11;
points[5].X = (int)247.83; 
points[5].Y = (int)220.11; 
points[6].X = (int)327.31; 
points[6].Y = (int)100.65;
Bitmap bmpInMemoryPoly( 160, 222); 
Image* ptrImagePoly = (Image*)&bmpInMemoryPoly; 
Graphics graphicsInMemoryPoly(ptrImagePoly );

// Set translation according to the Left Most 'X' point and the Top Most 'Y' point of the arrow
Matrix X1;
X1.Translate( 247, 100 );
graphicsInMemoryPoly.DrawImage( &image, 0, 0, 160, 222 );
TextureBrush tBrushPoly(ptrImagePoly );
tBrushPoly.SetWrapMode( WrapModeClamp );
// Set the translation to the image brush rect

graphics.DrawPolygon( &blackPen, points, iPointCount );
graphics.FillPolygon( &tBrushPoly, points, iPointCount );

delete [] points


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Virendra Kulkarni
Technical Lead Persistent Systems Ltd.
India India
I am currently working as a Tech Lead for VC++ projects. My role is to Design applications and to make them extensible and very easy to maintain. I use lot of design patterns into my work to design applications. I would like to share the knowledge gained while using these patterns with everybody.

You may also be interested in...


Comments and Discussions

-- There are no messages in this forum --
Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web02 | 2.8.181215.1 | Last Updated 20 Jun 2014
Article Copyright 2014 by Virendra Kulkarni
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid