如何将绿色指针图像居中绘制在尖形船舶图像之上?
解决绿色指针无法对齐船舶图像中心的问题
让我帮你排查代码里的问题,一步步修正就能让指针准确落在船舶中心了:
关键问题分析
- 指针中心计算错误:你用了
windImage.HorizontalResolution和VerticalResolution,这是图像的DPI分辨率,不是图像实际的宽高尺寸,完全不能用来计算中心位置。 - 绘制位置逻辑错误:
e.Graphics.DrawImage(image, Center(_shipImage))里的Center方法(假设是取中心)传递的是指针的中心坐标,但DrawImage的这个重载参数是图像左上角的位置,不是中心,所以指针会偏移。 - 冗余无用代码:
Bitmap img = new Bitmap(_shipImage);这段代码创建了船舶图像的副本,但完全没用到,属于无效代码。
修正后的完整代码
var shipImageOffset = new PointF(0, 0); using (var bmp = new Bitmap(_shipImage)) using (var image = ImageUtilities.RotateImage(bmp, (float)ShipHeading, new PointF(this.Width / 2, this.Height / 2), shipImageOffset, this.Width, this.Height)) { e.Graphics.DrawImage(image, new PointF(0, 0)); } // 绘制绿色指针图像 if (_windImageRepo.TryGetValue(needleSpeed, out var windImage)) { // 计算指针自身的中心(用图像实际宽高,不是分辨率) var needleCenter = new PointF(windImage.Width / 2f, windImage.Height / 2f); using (var bmp = new Bitmap(windImage)) { // 将非透明像素改为绿色 for (int x = 0; x < bmp.Width; x++) { for (int y = 0; y < bmp.Height; y++) { var color = bmp.GetPixel(x, y); if (color.A != 0) // 更准确判断非透明(Alpha通道不为0) { bmp.SetPixel(x, y, Color.LimeGreen); } } } var windImageOffset = new PointF(0, 0); // 旋转指针:以控件中心(也就是船舶中心)为旋转点 using (var rotatedNeedle = ImageUtilities.RotateImage(bmp, (float)WindHeading, new PointF(this.Width / 2, this.Height / 2), windImageOffset, this.Width, this.Height)) { // 计算指针左上角位置:让指针中心和船舶中心对齐 float drawX = (this.Width / 2f) - (rotatedNeedle.Width / 2f); float drawY = (this.Height / 2f) - (rotatedNeedle.Height / 2f); e.Graphics.DrawImage(rotatedNeedle, new PointF(drawX, drawY)); } } } base.OnPaint(e);
额外优化说明
- 我把判断透明像素的逻辑从
color != Color.FromArgb(0)改成了color.A != 0,这样更准确,因为有些透明像素可能不是完全的0值,Alpha通道判断更可靠。 - 明确了旋转中心是控件的中心(和船舶旋转的中心一致),这样旋转后的指针会围绕船舶中心转动,符合需求。
- 计算绘制位置时,用控件中心减去旋转后指针宽高的一半,确保指针的中心和船舶中心完全重合。
内容的提问来源于stack exchange,提问作者Waddaulookingat
相关产品推荐
相关产品推荐

