Sie sind auf Seite 1von 5

Scale a drawing so it fits a target area in C# - C# HelperC# Helper http://csharphelper.

com/blog/2014/11/scale-a-drawing-so-it-fits-a-target-area-in-c/

C# Helper
Tips, tricks, and example programs for
C# programmers.

Scale a drawing so it fits a target area in C#


Posted on November 7, 2014 by Rod Stephens

Many drawing programs need to scale a drawing to fit a target area, either with or
without stretching. The following MapDrawing method transforms a Graphics object so
it maps a drawing rectangle to a rectangle on the Graphics object.

// Map a drawing coordinate rectangle to


// a graphics object rectangle.
private void MapDrawing(Graphics gr, RectangleF drawing_rect,
RectangleF target_rect, bool stretch)
{
gr.ResetTransform();

1 de 5 19/12/2017 4:48 p. m.
Scale a drawing so it fits a target area in C# - C# HelperC# Helper http://csharphelper.com/blog/2014/11/scale-a-drawing-so-it-fits-a-target-area-in-c/

// Center the drawing area at the origin.


float drawing_cx = (drawing_rect.Left + drawing_rect.Right) / 2;
float drawing_cy = (drawing_rect.Top + drawing_rect.Bottom) / 2;
gr.TranslateTransform(-drawing_cx, -drawing_cy);

// Scale.
// Get scale factors for both directions.
float scale_x = target_rect.Width / drawing_rect.Width;
float scale_y = target_rect.Height / drawing_rect.Height;
if (!stretch)
{
// To preserve the aspect ratio,
// use the smaller scale factor.
scale_x = Math.Min(scale_x, scale_y);
scale_y = scale_x;
}
gr.ScaleTransform(scale_x, scale_y,
System.Drawing.Drawing2D.MatrixOrder.Append);

// Translate to center over the drawing area.


float graphics_cx = (target_rect.Left + target_rect.Right) / 2;
float graphics_cy = (target_rect.Top + target_rect.Bottom) / 2;
gr.TranslateTransform(graphics_cx, graphics_cy,
System.Drawing.Drawing2D.MatrixOrder.Append);
}

The code starts by resetting the Graphics object’s transformations to remove any previous transformations.

Next the code finds the center of the drawing rectangle and makes a transformation that translates the drawing so
it is centered at the origin. Then when the code scales the drawing in the next step, it remains centered at the
origin.

2 de 5 19/12/2017 4:48 p. m.
Scale a drawing so it fits a target area in C# - C# HelperC# Helper http://csharphelper.com/blog/2014/11/scale-a-drawing-so-it-fits-a-target-area-in-c/

The code then scales the drawing. It first finds scale factors that would make the drawing fill the target output
area. Then if the stretch parameter is false, indicating that you don’t want to stretch the result, the code sets both
scale factors to the smaller of the two. That makes the result as big as possible without distorting it.

The code then calls the Graphics object’s ScaleTransform method to scale the drawing. Notice the final parameter:
Append. This makes the new scale transformation come after the earlier translation. This is very important because
the order of the transformations is important. In general you cannot change the order of transformations and
produce the same result. (I have no clue why Microsoft decided the default should be to prepend new
transformation before older ones, but that’s what you get if you omit this final parameter.)

At this point the Graphics object is set up to make the drawing at its final scale centered at the origin. The code
now adds a transformation to move the center of the drawing (the origin) to the center of the target area. Again
notice that the code appends this transformation.

After you use this method to apply those transformations to the Graphics object, anything you draw on it will be
appropriately mapped to the target rectangle.

The following code shows how the program uses the MapDrawing method to draw the picture shown above.

// Draw some smiley faces.


private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode =
System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

RectangleF smiley_rect = new RectangleF(-1, -1, 2, 2);

3 de 5 19/12/2017 4:48 p. m.
Scale a drawing so it fits a target area in C# - C# HelperC# Helper http://csharphelper.com/blog/2014/11/scale-a-drawing-so-it-fits-a-target-area-in-c/

float wid = (this.ClientSize.Width - 1) / 2;


float hgt = (this.ClientSize.Height - 1) / 2;

// Draw in the upper left quarter.


MapDrawing(e.Graphics, smiley_rect,
new RectangleF(0, 0, wid, hgt), false);
DrawSmiley(e.Graphics);

// Draw in the lower left quarter.


MapDrawing(e.Graphics, smiley_rect,
new RectangleF(0, hgt, wid, hgt), false);
DrawSmiley(e.Graphics);

// Draw in the right side.


MapDrawing(e.Graphics, smiley_rect,
new RectangleF(wid, 0, wid, 2 * hgt), true);
DrawSmiley(e.Graphics);
}

The DrawSmiley method uses ellipses and an arc to draw a smiley face in the area (-1, -1)-(1, 1). It’s straightforward
so it isn’t shown here. Download the example to see how it works.

The Paint event handler RectangleF named smiley_rect to represent the area where the smiley should be drawn.
It also makes variables wid and hgt to measure half of the form’s client area (minus 1 so things fit at the edges).

Next the code calls MapDrawing and DrawSmiley to draw the smiley face on different parts of the form. Notice that
the first two calls to DrawSmiley use false for their last parameters so those smiley faces are not distorted. In the
final call to DrawSmiley, this parameter is true so the smiley is stretched to fill the entire target area.

4 de 5 19/12/2017 4:48 p. m.
Scale a drawing so it fits a target area in C# - C# HelperC# Helper http://csharphelper.com/blog/2014/11/scale-a-drawing-so-it-fits-a-target-area-in-c/

This entry was posted in algorithms, drawing, graphics, mathematics and tagged algorithms, C#, C# programming, drawing, example, example program, graphics, mathematics,
scale drawing, scale to fit, Windows Forms programming. Bookmark the permalink.

C# Helper
Proudly powered by WordPress.

5 de 5 19/12/2017 4:48 p. m.

Das könnte Ihnen auch gefallen