要重现此问题,请在Microsoft Paint中创建一个2x2像素的黑色图像,另存为D:\small.png
.然后在Visual Studio中创建一个新的WinForms应用程序,带有无边距的PictureBox.然后使用以下代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
我希望蓝色边距内的整个矩形是黑色的,而输出如下:
为什么会这样?
好,谢谢.我不知道插值.现在,让我们更改代码如下:
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);
}
Run Code Online (Sandbox Code Playgroud)
它产生以下结果:
这仍然是不可接受的.我也试过了60x60的图像.问题不在于它是2x2的图像.它们产生同样的效果.问题是为什么GDI +决定不用整个srcRect填充整个destRect?!最初的问题是我有一个较小的图像.我需要相邻的瓷砖,它们之间既不重叠也不存在接缝.在C++中,StretchBlt正常工作.但它不会产生平滑的拉伸图像.
GDI +对源矩形的定义有点奇怪.
源图像中的(0,0)实际上是图像中左上像素的中心.(width-1,height-1)是图像中右下像素的中心.
这意味着左上角像素是从(-0.5,-0.5)到(0.5,0.5)的矩形,右下角像素是从(宽度-1.5,高度-1.5)到(宽度-0.5)的矩形,高度0.5).因此,您的源矩形实际上在图像外部向右和向下0.5像素.
所以,你实际上需要一个源矩形(-0.5,-0.5,img.Width,img.Height).
我想你也可以尝试设置PixelOffsetMode,就像Hans建议的那样.这实际上会理解行为,但我不希望它适用于源矩形.