解决  帮助DrawImage(图像图像,int x,int y)

tim8w

知名会员
已加入
2020年9月8日
留言内容
81
编程经验
10+
我有一个定义为(0,40,475,244)的矩形,要在其中绘制128x128图像。我打电话给DrawImage如下:

C#:
Point pImage = new Point();
pImage.X = (rPanel.Right - rPanel.Left) / 2 - this.BackgroundImage.Size.Width / 2;
pImage.Y = (rPanel.Bottom - rPanel.Top) / 2 - this.BackgroundImage.Size.Height / 2;
g.DrawImage(this.BackgroundImage, pImage.X, pImage.Y);

生成的图像最终在错误的位置绘制。

1613196276693.png


应该更像这样:

1613196338589.png


我知道这一定很明显,但是我看不出Image位置的计算出了什么问题...
 
Solution
我设法重现了您的问题。

打开.png文件,看起来它的格式为72 dpi,而Windows默认为96 dpi。因此,您需要让Windows将图像缩放到适当的区域。就像是:
C#:
var ptImage = new Rectangle()
{
    X = rect.Width / 2 - _img.Width / 2 + rect.Left,
    Y = rect.Height / 2 - _img.Height / 2 + rect.Top,
};

g.DrawImage(_img, new Rectangle(ptImage, _img.Size));

In the image below, notice the bigger image drawn by DrawImage(Image, Point), and then painted over by the DrawImage(Image, Rectangle) which is right in the green rectangle where we expected the image to be drawn into.

Screenshot_1.png

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,553
地点
悉尼,澳大利亚
编程经验
10+
Please provide a FULL and CLEAR explanation of the problem. You say that you have a Rectangle. OK then. How exactly does that relate to the code? What is this in that code? We need ALL the relevant information.
 

tim8w

知名会员
已加入
2020年9月8日
留言内容
81
编程经验
10+
Please provide a FULL and CLEAR explanation of the problem. You say that you have a Rectangle. OK then. How exactly does that relate to the code? What is this in that code? We need ALL the relevant information.
抱歉,矩形描述了标题下方的面板。我试图将图像居中放置在该矩形中。
 

tim8w

知名会员
已加入
2020年9月8日
留言内容
81
编程经验
10+
如果存在偏移,则必须计算宽度/高度的中心,然后偏移位置。
我知道了这就是我在这里所做的:

C#:
Point pImage = new Point();
pImage.X = (rPanel.Right - rPanel.Left) / 2 - this.BackgroundImage.Size.Width / 2;
pImage.Y = (rPanel.Bottom - rPanel.Top) / 2 - this.BackgroundImage.Size.Height / 2;
g.DrawImage(this.BackgroundImage, pImage.X, pImage.Y);

但是,如您在上图中所见,即使计算正确,它也无法正确定位。面板矩形为(0,40,475,244),图像为128x128。 DrawImage的最终起点是(173,38)。当它绘制图像时,它似乎偏离了中心。 X位置似乎偏右约23,Y位置似乎偏高约16。是否有一些像素转换我没有考虑到?托管表单AutoScaleMode设置为"None".
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,580
地点
弗吉尼亚州切萨皮克
编程经验
10+
Are you sure that the image really is 128x128? What values are you getting in the debugger for this.BackgroundImage.Size.Width and this.BackgroundImage.Size.Height?
 

tim8w

知名会员
已加入
2020年9月8日
留言内容
81
编程经验
10+
Are you sure that the image really is 128x128? What values are you getting in the debugger for this.BackgroundImage.Size.Width and this.BackgroundImage.Size.Height?
大小绝对是128x128。因此,当我在X的表单中减去面板(21,22)的实际位置时,即从计算出的最终位置中减去21时,它在X中就完全对齐。如果我需要对X进行此操作,我必须对Y做同样的事情吗?
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,580
地点
弗吉尼亚州切萨皮克
编程经验
10+
尝试运行以下命令:
C#:
Point pImage = new Point();
pImage.X = (rPanel.Right - rPanel.Left) / 2 - this.BackgroundImage.Size.Width / 2;
pImage.Y = (rPanel.Bottom - rPanel.Top) / 2 - this.BackgroundImage.Size.Height / 2;
g.DrawImage(this.BackgroundImage, pImage.X, pImage.Y);
g.DrawRectangle(new Pen(Color.Green, 3), new Rectangle(pImage, this.BackgroundImage.Size));

然后截取屏幕截图并将其发布到此线程。我想知道图像是否为128x128,但是图像的实际内容并不是真正的边缘到边缘。
 

tim8w

知名会员
已加入
2020年9月8日
留言内容
81
编程经验
10+
尝试运行以下命令:
C#:
Point pImage = new Point();
pImage.X = (rPanel.Right - rPanel.Left) / 2 - this.BackgroundImage.Size.Width / 2;
pImage.Y = (rPanel.Bottom - rPanel.Top) / 2 - this.BackgroundImage.Size.Height / 2;
g.DrawImage(this.BackgroundImage, pImage.X, pImage.Y);
g.DrawRectangle(new Pen(Color.Green, 3), new Rectangle(pImage, this.BackgroundImage.Size));

然后截取屏幕截图并将其发布到此线程。我想知道图像是否为128x128,但是图像的实际内容并不是真正的边缘到边缘。
 

附件

  • 1613268422553.png
    1613268422553.png
    27.3 KB · Views: 3

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,580
地点
弗吉尼亚州切萨皮克
编程经验
10+
在我看来,这告诉您该图像仅在整个图像区域的右下角包含红色箭头。
 

tim8w

知名会员
已加入
2020年9月8日
留言内容
81
编程经验
10+
好的。让我们重新开始。我有一个具有以下大小的面板:(0,40,475,244)。页眉占据了顶部40个像素,因此当我将Image放在面板下部时,我不希望考虑它们。我正在使用的测试图像是128x128。图片不会占用整个128x128。顶部和底部短,而左侧和右侧短。所以我想使图像居中的区域是(0,40,475,204)(原始面板减去40像素标题)

我试过的计算是:

C#:
Point pImage = new Point();
pImage.X = (rPanel.Right - rPanel.Left) / 2 - this.BackgroundImage.Size.Width / 2;
pImage.Y = (rPanel.Bottom - rPanel.Top) / 2 - this.BackgroundImage.Size.Height / 2;
g.DrawImage(this.BackgroundImage, pImage.X, pImage.Y);

其中rPanel为(0,40,475,204)和this.BackgroundImage.Size =(128,128)


当我使用此计算时,图像未居中。它向上移动并向右移动。

1613276677753.png


我希望它集中于以下内容:

1613276757421.png
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,580
地点
弗吉尼亚州切萨皮克
编程经验
10+
我正在使用的测试图像是128x128。图片不会占用整个128x128。顶部和底部短,而左侧和右侧短。
但这不是那个淹没在与图像相同位置的绿色矩形所讲述的故事。它显示图像实际上被卡在128x128区域的右下角。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,580
地点
弗吉尼亚州切萨皮克
编程经验
10+
啊!因此,图像不仅包含箭头,而且包含看起来像其周围的窗口镶边的框。

现在,如果绿色矩形与图像相距太远,那真是一团糟。

Do you change any of the graphics context's translate or origin values? What happens when you add g.Transform.Reset() before drawing the image and the green rectangle?
 

tim8w

知名会员
已加入
2020年9月8日
留言内容
81
编程经验
10+
啊!因此,图像不仅包含箭头,而且包含看起来像其周围的窗口镶边的框。

现在,如果绿色矩形与图像相距太远,那真是一团糟。

Do you change any of the graphics context's translate or origin values? What happens when you add g.Transform.Reset() before drawing the image and the green rectangle?
结果相同:

1613322045520.png
 

tim8w

知名会员
已加入
2020年9月8日
留言内容
81
编程经验
10+
这里是
可以上传png文件吗?这里真的很奇怪。
这是...实际上,任何图像都可以。我只是在检查代码,以查看是否可以居中,平铺等方式绘制背景图像。我唯一能够正确绘制的是“无”和“拉伸”。
 

附件

  •  坍塌 Panel128.png
    坍塌 Panel128.png
    16.3 KB · Views: 4

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,580
地点
弗吉尼亚州切萨皮克
编程经验
10+
坚持,稍等。这里有些奇怪。 rPanel.Left如何设置为0,但是面板左侧有黑色到蓝色的渐变呢?该rPanel是否在其他控件中?
 
最佳 底部