VB.NET自定义用户控制图形旋转

发布于 2024-09-03 09:50:43 字数 645 浏览 4 评论 0原文

这是我在这里提出的第一个问题。 我正在尝试在 VB.NET 中构建一个拨号控件作为自定义用户控件。我用的是VS2008。

到目前为止,我已成功使用graphics.rotatetransform 旋转图像。然而,这会旋转一切。现在我有一个用于表盘的位图,它应该保持稳定,还有另一个用于我需要旋转的针的位图。

到目前为止我已经尝试过这个:

Dim gL As Graphics = Graphics.FromImage(bmpLongNeedle)
    gL.TranslateTransform(bmpLongNeedle.Width / 2, bmpLongNeedle.Height * 0.74)
    gL.RotateTransform(angleLongNeedle)
    gL.TranslateTransform(-bmpLongNeedle.Width / 2, -bmpLongNeedle.Height * 0.74)
    gL.DrawImage(bmpLongNeedle, 0, 0)

据我了解,针的图像应该以角度“angleLongNeedle”旋转,尽管我将旋转的图像放置在0,0处。然而,结果是 Needle 没有绘制在控件上。

关于我可能出错的地方或者我应该做的其他事情有什么指示吗?

提前致谢

this is my first question on here.
I'm trying to build a dial control as a custom user control in VB.NET. I'm using VS2008.

so far I have managed to rotate image using graphics.rotatetransform . however, this rotate everything. Now I have a Bitmap for the dial which should stay stable and another Bitmap for the needle which I need to rotate.

so far i've tried this:

Dim gL As Graphics = Graphics.FromImage(bmpLongNeedle)
    gL.TranslateTransform(bmpLongNeedle.Width / 2, bmpLongNeedle.Height * 0.74)
    gL.RotateTransform(angleLongNeedle)
    gL.TranslateTransform(-bmpLongNeedle.Width / 2, -bmpLongNeedle.Height * 0.74)
    gL.DrawImage(bmpLongNeedle, 0, 0)

As I understand it, the image of the needle should be rotated at angle "angleLongNeedle" although i'm placing the rotated image at 0,0. However, the result is that the Needle doesn't get drawn on the control.

any pointers as to where I might be going wrong or something else I should be doing?

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

那支青花 2024-09-10 09:50:43

首先,为什么要从位图中分配 Graphics 对象,然后将其绘制到图形上?这没有道理。

Dim gL As Graphics = Graphics.FromImage(bmpLongNeedle)
' … '
gL.DrawImage(bmpLongNeedle, 0, 0)

您可能想要的是整个图像的图形上下文。然后对其应用转换并最终绘制 bmpLongNeedle 图像。

其次,你的翻译看起来是相反的:第一步,你需要将图像移动到原点 (0, 0);然后旋转它,然后将其移回来。因此,转换应该如下所示:

gL.TranslateTransform(-bmpLongNeedle.Width * 0.5, -bmpLongNeedle.Height * 0.5)
gL.RotateTransform(angleLongNeedle)
gL.TranslateTransform(bmpLongNeedle.Width * 0.5, bmpLongNeedle.Height * 0.5)

注意 TranslateTransform 的相反顺序。另外,为什么你平移高度的 0.74 倍,而不是一半?

First of all, why do you allocate the Graphics object from a bitmap that you then proceed to draw onto the graphics? That doesn’t make sense.

Dim gL As Graphics = Graphics.FromImage(bmpLongNeedle)
' … '
gL.DrawImage(bmpLongNeedle, 0, 0)

What you probably want is a graphics context for the whole image. You then apply the transformations to it and finally draw the bmpLongNeedle image.

Secondly, your translations look inversed: in the first step, you need to move the image to the origin (0, 0); then you rotate it, and then move it back. So the transformation should look like this:

gL.TranslateTransform(-bmpLongNeedle.Width * 0.5, -bmpLongNeedle.Height * 0.5)
gL.RotateTransform(angleLongNeedle)
gL.TranslateTransform(bmpLongNeedle.Width * 0.5, bmpLongNeedle.Height * 0.5)

Notice the inversed order of the TranslateTransforms. Also, why did you translate by 0.74 times the height, instead of half?

段念尘 2024-09-10 09:50:43

哦,针的位图的枢轴点位于 0.74 * 高度。

也许我应该之前发布这个。但这就是我所做的。


Public Class Altimeter
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        Dim bmpBezel As New Bitmap("{path}\Altimeter_Background.bmp")
        Dim bmpLongNeedle As New Bitmap("{path}\LongNeedle.bmp")
        Dim rect2 As New Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width, e.ClipRectangle.Height)

'make transparent bmpBezel.MakeTransparent(Color.Yellow) bmpLongNeedle.MakeTransparent(Color.Yellow) Dim angleLongNeedle As Single = (Altitude / 50) * 360 'draw bezel e.Graphics.DrawImage(bmpBezel, rect2) 'rotate long needle Dim gL As Graphics = Graphics.FromImage(bmpLongNeedle) gL.TranslateTransform(bmpLongNeedle.Width / 2, bmpLongNeedle.Height * 0.74) gL.RotateTransform(angleLongNeedle) gL.TranslateTransform(-bmpLongNeedle.Width / 2, -bmpLongNeedle.Height * 0.74) gL.DrawImage(bmpLongNeedle, 0, 0) MyBase.OnPaint(e) End Sub

我使用 e.graphics.drawimage 来绘制整个图像。我真的不明白你所说的为所有图像设置图形对象然后绘制针是什么意思?你有伪代码吗?
谢谢

oh the bitmap for needle has the pivot point at 0.74 * height.

may be I should have posted this before. but this is what i've done.


Public Class Altimeter
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        Dim bmpBezel As New Bitmap("{path}\Altimeter_Background.bmp")
        Dim bmpLongNeedle As New Bitmap("{path}\LongNeedle.bmp")
        Dim rect2 As New Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width, e.ClipRectangle.Height)

'make transparent bmpBezel.MakeTransparent(Color.Yellow) bmpLongNeedle.MakeTransparent(Color.Yellow) Dim angleLongNeedle As Single = (Altitude / 50) * 360 'draw bezel e.Graphics.DrawImage(bmpBezel, rect2) 'rotate long needle Dim gL As Graphics = Graphics.FromImage(bmpLongNeedle) gL.TranslateTransform(bmpLongNeedle.Width / 2, bmpLongNeedle.Height * 0.74) gL.RotateTransform(angleLongNeedle) gL.TranslateTransform(-bmpLongNeedle.Width / 2, -bmpLongNeedle.Height * 0.74) gL.DrawImage(bmpLongNeedle, 0, 0) MyBase.OnPaint(e) End Sub

i use e.graphics.drawimage to paint the whole image. i don't really understand what you said about having graphics object for all the images and then drawing the needle? do you have any pseudo code?
thanks

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文