I have a Winforms application that uses Graphics.DrawImage
to stretch and draw a bitmap, and I need help understanding how the source pixels map to the destination.
Ideally, I want to write a function like:
Point MapPixel(Point p, Size src, Size dst)
which takes the coordinate of the pixel in the original image and returns the coordinate of the "upper left" pixel corresponding to it at the scaled destination.
For clarity, a trivial example is presented here in which a 2x2 bitmap is scaled to 4x4:

The arrow shows how to feed the point (1,0) into MapPixel:
MapPixel(new Point(1, 0), new Size(2, 2), new Size(4, 4))
should give the result (2.0).
It is easier to make MapPixel work for the above example using logic, for example:
double scaleX = (double)dst.Width / (double)src.Width;
x_dst = (int)Math.Round((double)x_src * scaleX);
, - , dst.Width
src.Width
. DrawImage , , , , .
2x1 :
Bitmap src = new Bitmap(2, 1);
src.SetPixel(0, 0, Color.Red);
src.SetPixel(1, 0, Color.Blue);
Bitmap[] dst = {
new Bitmap(3, 1),
new Bitmap(5, 1),
new Bitmap(7, 1),
new Bitmap(9, 1)};
foreach (Bitmap b in dst) {
using (Graphics g = Graphics.FromImage(b)) {
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.PixelOffsetMode = PixelOffsetMode.Half;
g.DrawImage(src, 0, 0, b.Width, b.Height);
}
}
src
dst
, , , MapPixel :

, DrawImage , . , , . , , , .
MapPixel, MidpointRounding.AwayFromZero
, Math.Round
, ( , ). Graphics - ScaleTransform
, DrawImageUnscaled
, TransformPoints
. , TransformPoints , DrawImage DrawImageUnscaled.
GDI + , .
, , .
, , , InterpolationMode.NearestNeighbor
, - ( ), PixelOffsetMode.Half
, , DrawImage .
x = 7 4px 13px x = 8 4px 17px.
unit test, , MapPixel. 100- - , "", . , , , . (, , ), .
, - DrawImage ( ) MapPixel.