C# 中的交互式缩放 2D 图形位图

发布于 2024-12-05 11:27:30 字数 401 浏览 1 评论 0原文

我编写了一个程序,可以从 xml 文件中读取一些二极管曲线的电压和电流值,并将它们绘制在屏幕上(只需使用普通的 2D 图形和一些简单的命令,如 DrawCurve 等)。

我的主图像帧是 800 x 800 像素(您可以在下面看到较小的屏幕截图)。现在我想添加一个缩放功能,当我将鼠标悬停在该图像区域上时,会弹出一个飞行的小方块,并在将鼠标移动到该区域上时放大+移动。

我不知道如何处理这个问题。当然,我不会询问完整的工作代码,但请帮助我越来越接近!

例如,我可以在不读取曲线数据和实时绘制的情况下进行缩放吗?还是无法逃脱?当我将鼠标移到原始图像上时,如何才能有一个悬停图像框?

谢谢!

在此处输入图像描述

I have made a program that reads voltage and current values of some diode curves from an xml file and draws them on screen (Just using plain 2D graphics and some simple commands like DrawCurve and stuff like that).

My main image frame is 800 by 800 pixels (you can see a smaller screenshot down below). Now I want to add a zoom function that when I hover the mouse over this image area, a flying smaller square pops up and zooms in + moves when I move the mouse over this area.

I have no idea how to approach this. Ofcourse I don't ask the full working code but please help me to get closer and closer!

For instance, can I make the zoom to work, without reading the curve data and painting real time? or there is no escape from it? How can I have a hovering image box when I move mouse over the orginal image?

Thanks!

enter image description here

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

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

发布评论

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

评论(2

尘曦 2024-12-12 11:27:30

您是否计算过 DrawCurve 需要多长时间?也许它足够快,可以实时完成。不要忘记,GDI 会将绘图基元剪切到绘图区域。您只需在移动鼠标时设置一个剪切矩形即可。

要加快重绘速度,请将主窗口图像(您粘贴的图像)创建为离屏位图,然后在绘制事件中将离屏版本 DrawImage 绘制到窗口。这样您就可以减少 DrawCurve 的影响。

最后,为了获得好看的结果,请重载 OnPaintBackground(无法准确记住名称,但它是类似的东西),因此它不执行任何操作(甚至不调用基类)并在其中完成所有绘画使用 BufferedGraphics 对象的 OnPaint 方法。

更新

您的绘图函数可能如下所示:

OnPaint (...)
{
  the_graphics_object.DrawImage (the background image);
  the_graphics_object.Clip = new Region (new Rectangle (coords relative to mouse position));
  the_graphics_object.TranslateTransform (drawing offset based on mouse position);
  RenderScene (the_graphics_object, scale_factor); // draws grid and curve, etc
  the_graphics_object.DrawRectangle (zoom view rectangle); // draw a frame around the zoomed view
}

这将产生一个相对于鼠标位置的浮动“窗口”。

Have you timed how long DrawCurve takes? Perhaps it's fast enough to do in real time. Don't forget, the GDI will clip the drawing primitives to the drawing area. You just need to set up a clipping rectangle as you move the mouse around.

To speed up the redraw, create the main window image (the one you pasted) as an off-screen bitmap, and just DrawImage the off-screen version to the window in the paint events. That way you reduce the impact of the DrawCurve.

Finally, to get good looking results, overload the OnPaintBackground (can't remember the name exactly but it's something like that) so it does nothing (not even call the base class) and do all your painting in the OnPaint method using a BufferedGraphics object.

Update

Your paint function might look like this:

OnPaint (...)
{
  the_graphics_object.DrawImage (the background image);
  the_graphics_object.Clip = new Region (new Rectangle (coords relative to mouse position));
  the_graphics_object.TranslateTransform (drawing offset based on mouse position);
  RenderScene (the_graphics_object, scale_factor); // draws grid and curve, etc
  the_graphics_object.DrawRectangle (zoom view rectangle); // draw a frame around the zoomed view
}

This will produce a floating 'window' relative to the mouse position.

兔姬 2024-12-12 11:27:30

通常,在重绘可能非常耗时的情况下,缩放通常通过提供“快速但丑陋”的实现以及“正确但缓慢”的实现来解决。当缩放操作正在积极进行时(例如,当用户单击滑块时,或者直到自上次缩放值发生更改以来 50 毫秒),您使用快速且丑陋的模式,因此用户可以看到预览最终的图像会是什么。一旦他们放开缩放滑块(或您提供的任何机制),您就可以重新详细计算图像。快速版本通常是根据您正在使用的原始图像计算的。

在您的情况下,您可以简单地获取原始图像,计算出新的缩放图像的边界框,并将原始图像的相关部分缩放到完整图像大小。如果 100 毫秒过去了,缩放没有变化,则重新计算整个图像。

这种功能的例子非常普遍:大多数分形生成器都使用这种技术,甚至像 Google StreetView 这样不相关的东西(当你四处移动时,它会提供前一个图像的非常丑陋的扭曲版本,直到实际图像下载完毕)。

Typically, cases where redrawing can be time consuming, zooming is usually tackled by providing a "quick but ugly" implementation, alongside the "correct but slow" implementation. While the zoom operation is actively in progress (say, while the user has a slider clicked, or until a 50ms since the last change in zoom value has happened), you use the quick and ugly mode, so the user can see a preview of what the final image will be. Once they let go of the zoom slider (or whatever mechanism you provided), you can recalculate the image in detail. The quick version is usually calculated based on the original image that you are working with.

In your case, you could simply take the original image, work out the bounding box of the new, zoomed image, and scale the relevant part of the original image up to the full image size. If say 100ms has passed with no change in zoom, recalculate the entire image.

Examples of this kind of functionality are quite widespread: most fractal generators use exactly this technique, and even unrelated things like Google StreetView (which provides a very ugly distorted version of the previous image when you move around, until the actual image has downloaded).

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