Title: Use DrawImage to warp images in C#
The examples Warp images arbitrarily in C#, Part 1 and Warp images arbitrarily in C#, Part 2 show how to use inverse transformations to warp images arbitrarily. The Graphics class's DrawImage method also lets you warp images. It's not as flexible but it's a lot easier.
The DrawImage method has 30 different overloaded versions. One of those takes as parameters three points that represent where the routine should map the upper left, upper right, and lower left corners of the original image. The method figures out where to put the fourth corner to make the resulting figure a parallelogram. You can use this version of DrawImage to warp images.
(It would have been even better if it also let the programmer specify where to put all four points. Then you could perform the more useful mappings needed for three-dimensional graphics. Alas, that's not the way it works.)
This example uses the following code to map an image's corners to new points that reflect and warp the image.
private void Form1_Load(object sender, EventArgs e)
{
// Get the source bitmap.
Bitmap bm_source = new Bitmap(picSource.Image);
// Make an array of points defining the
// transformed image's corners.
int wid = bm_source.Width;
int hgt = bm_source.Height;
PointF[] corners =
{
new PointF(wid * 0.5f, 0),
new PointF(0, hgt * 0.4f),
new PointF(wid, hgt * 0.6f)
};
// Make a bitmap for the result.
Bitmap bm_dest = new Bitmap(
(int)bm_source.Width,
(int)bm_source.Height);
// Make a Graphics object for the result Bitmap.
using (Graphics gr_dest = Graphics.FromImage(bm_dest))
{
// Copy the source image into the destination bitmap.
gr_dest.DrawImage(bm_source, corners);
// Display the result.
picDest.Image = bm_dest;
}
}
The code creates an array of PointF to define where DrawImage should map the source image's upper left, upper right, and lower left corners. It then makes a destination Bitmap and an associated Graphics object. It uses that object's DrawImage method to draw the original image onto the Bitmap, warping it in the process. The code finishes by displaying the result.
Download the example to experiment with it and to see additional details.
|