I'm experiencing unexpected results from Graphics.DrawImage
.net, c#, gdi+
Solution
GDI+'s definition of the source rectangle is a bit odd.
(0,0) in the source image is actually the center of the upper-left pixel in the image. (width-1,height-1) is the center of the lower-right pixel in the image.
That means that the upper-left pixel is the rectangle from (-0.5,-0.5) to (0.5,0.5), and the lower-right pixel is the rectangle from (width-1.5,height-1.5) to (width-0.5,height-0.5). Thus, your source rectangle is actually outside the image by 0.5 pixels to the right and bottom.
So, you actually need a source rectangle of (-0.5, -0.5, img.Width, img.Height).
I guess you can also try setting PixelOffsetMode as Hans suggests. That would actually make sense of the behavior, but I wouldn't have expected it to apply to source rectangles.
Problem
To reproduce this issue, please create a 2x2 pixel black image in Microsoft Paint, saved as `D:\small.png`. Then create a new WinForms app in Visual Studio, with a no-margin PictureBox. Then use the following code: ``` void f6(Graphics g) { var img = Image.FromFile(@"d:\small3.png"); var srcRect = new Rectangle(0, 0, img.Width, img.Height); int factor = 400; var destRect = new Rectangle(0, 0, img.Width * factor, img.Height * factor); g.DrawRectangle(new Pen(Color.Blue), destRect); g.DrawImage(img, destRect, srcRect, GraphicsUnit.Pixel); } void pictureBox1_Paint(object sender, PaintEventArgs e) { f6(e.Graphics); } ``` I expect the entire rectangle inside the blue margins be black while the output is as follows: Why is this happening? ok, thanks. i din't know about interpolation. now, let's change the code as following: ``` void f6(Graphics g) { var img = Image.FromFile(@"d:\small3.png"); var srcRect = new Rectangle(0, 0, img.Width, img.Height); int factor = 200; var destRect = new Rectangle(0, 0, img.Width * factor, img.Height * factor); g.FillRectangle(new SolidBrush(Color.DarkCyan), pictureBox1.ClientRectangle); g.InterpolationMode = InterpolationMode.NearestNeighbor; g.DrawRectangle(new Pen(Color.Blue), destRect); g.DrawImage(img, destRect, srcRect, GraphicsUnit.Pixel); } ``` it produces the following result: Result3 which is still unacceptable. i've tried 60x60 images too. the problem is not because it's a 2x2 image. they produce the same effect. the problem is that why GDI+ decides not to fill the entire destRect with the entire srcRect?! the original problem is that i've a big image tiled in smaller ones. i need adjacent tiles neither overlap nor seam exist between them. in C++, StretchBlt works properly. but it doesn't produce a smooth stretched image.