我遇到的Graphics.DrawImage意外的结果 [英] I'm experiencing unexpected results from Graphics.DrawImage

查看:275
本文介绍了我遇到的Graphics.DrawImage意外的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要重现此问题,请创建一个2x2像素的黑色图像在Microsoft画图,保存为 D:\ small.png 。然后在Visual Studio中的一个新的WinForms应用程序,有没有利润的图片框。然后使用以下code:

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:

这是怎么回事?

好的,谢谢。我din't了解插值。现在,让我们改变了code如下:

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

这仍然是不能接受的。 我试过60x60的图像了。这个问题是不是因为它是一个2x2的形象。它们产生相同的效果。的问题是,为何GDI +决定不填充整个srcRect整个destRect? 原来的问题是,我已经平铺较小的一个大的图像。我需要相邻的地砖之间没有重叠,也没有焊缝存在。在C ++中,StretchBlt工作正常。但它不产生一个平滑的拉伸图像。

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.

推荐答案

源矩形的GDI +的定义是有点奇怪。

GDI+'s definition of the source rectangle is a bit odd.

(0,0)的源图像中实际上是图像中的左上角像素的中心。 (宽度-1,高度-1)是在图像中的右下角的像素的中心。

(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.

这意味着,左上角像素是从(-0.5,-0.5)的矩形(0.5,0.5),和右下角的像素是从(宽度-1.5,高度1.5)于矩形(宽0.5,高度0.5)。因此,你的源矩形实际上是外树形象0.5像素的权利和底部。

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.

所以,你真正需要的源矩形(-0.5,-0.5,img.Width,img.Height)。

So, you actually need a source rectangle of (-0.5, -0.5, img.Width, img.Height).

我想你也可以尝试设置PixelOffsetMode为汉斯建议。这实际上使行为的意义,但我也不会预料到适用于源矩形。

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.

这篇关于我遇到的Graphics.DrawImage意外的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆