求教 C# 绘图问题

2020-11-06 14:28:16 +08:00
 iSNN

老师给的一个课题:

用 C# 实现一个路况图,不需要 GIS 那样的,会给出道路的信息(横竖或者 45°这种简单的直线)和红绿灯,还有车辆的实时位置,车最多给十辆吧。要有缩放和拖动功能,1 秒刷一次

各位大佬有什么好的方案吗...

我现在是用 Graphics 来做的,Bitmap 手动做的二级缓存,缩放试过了 graphics 的 ScaleTransform,试过了构造函数直接给个新 size 再 new 一个 bitmap 来,试过了 drawimage 来缩放,但是效率都太低了,太卡了。调了 BitBlt 也还是太慢。

请问各位大佬有好的方案吗?

2085 次点击
所在节点    程序员
29 条回复
GM
2020-11-06 14:36:56 +08:00
这问题,看得头皮发麻。。。。。


“GIS 那样的”是怎样?

“不需要 GIS 那样的”是什么意思?

“效率太低”指的是缩放的时候效率低,还是所有时候效率都低?


最后:
缩放为什么会需要 ScaleTransform 、new Bitmap 、drawimage ?计算好比例,直接用 g.drawXxx 画到 buffer 里,然后 BitBlt 出来不就好了吗?
shaderlab
2020-11-06 14:42:04 +08:00
用 Unity3D 呀,也算 C# 开发吧,实现你这个功能太容易了
iSNN
2020-11-06 14:50:07 +08:00
@GM GIS 那样就是要和真实地理信息结合,有海拔那些什么乱七八糟的,曲折的。不要那么具体的,地图只是简单的横竖 45°组成。效率低缩放是最严重的,其余也不高,明显感觉卡顿。
缩放直接用 DrawXxx 不是 drawimage 吗?
across
2020-11-06 14:54:13 +08:00
嵌入 OpenGL/DirectX
xxiu
2020-11-06 14:55:52 +08:00
需要将变化的和不变的独立出来,每次只在不变的上面画变化的,双缓冲,也就是 bitmap 变化异步刷新到界面。
kanezeng
2020-11-06 14:56:23 +08:00
Unity 吧,2D/3D 都简单。
MinQ
2020-11-06 14:58:35 +08:00
这是 AGV 的实时监控吧,网上有个开源的 DragCanvas
MinQ
2020-11-06 14:58:56 +08:00
@kanezeng 用 Unity 就整复杂了
MinQ
2020-11-06 15:02:48 +08:00
iSNN
2020-11-06 15:17:52 +08:00
@MinQ 感谢,我去看看这个。你这么一说 AGV 实时监控我开始怀疑是一个商业课题,被迫免费劳动力 2333
GM
2020-11-06 15:24:15 +08:00
你对二级缓存理解错误了,Bitmap 做二级缓存不是这样做的。

感觉你是做成了先画一张大图到 Bitmap 里,然后想通过缩放图片的方式来做缩放,这样当然慢了,奇慢无比。

Bitmap 做二级缓存,是在需要更新画面的时候,不直接往屏幕上 DrawXxx,而是先往缓存 Bitmap 里 DrawXxx,所有东西都 Draw 完后,一句 BitBlt 直接输出到显示屏上,避免了直接在屏幕上各种 Draw 导致的闪烁。
xdtr
2020-11-06 15:40:44 +08:00
使用 BufferedGraphicsContext 和 BufferedGraphics
MinQ
2020-11-06 15:42:22 +08:00
@GM 话说这个不需要二级缓冲吧,就建个 WPF 的工程,搞个 Canvas 把车辆和地图上的标识当成组件扔进去,然后建个定时器,更新一下车辆组建的位置就完事了。画界面的破事都让 WPF 后面的 DirectX 处理去,这种量级的界面重绘根本就不需要二级缓冲
iSNN
2020-11-06 15:53:03 +08:00
@GM 那请问怎么缩放呢?都 BitBlt 我不会直接往屏幕上 Draw 的......
rocbomb
2020-11-06 15:57:16 +08:00
@MinQ 我觉得反倒简单了
这种需求,用 Unity 的 2d 一下午就撸出来了,而且绝对不会有性能问题
rocbomb
2020-11-06 16:00:08 +08:00
或者 monogame
这个需求用游戏引擎来解决,会非常舒服
MinQ
2020-11-06 16:11:21 +08:00
@rocbomb 本来用控件就不会有性能问题,这种项目我是做过的,用 Unity 的话还要学一堆 Unity2D 的东西,我个人觉得是犯不着。
GM
2020-11-06 16:33:52 +08:00
@iSNN
大概是这样:
假设你显示区域大小为 W 、H,缩放系数为 x
需要 new 一个和你目标显示区域一样大小的 bitmap,
然后根据当前缩放比例,往 bitmap 上 draw 各种元素,也就是你说的横竖、斜 45 度的线条。
draw 完后,BitBlt 到显示区域对应的 Graphics 对象中。
完事。
iSNN
2020-11-06 16:37:13 +08:00
@GM 您的意思是,重新绘图,比缩放图片要快?我确实没有缩放后再画线,我是一个原图,然后路线啊,红绿灯位置这些固定的画好,然后缩放后再画动态的东西,再 BitBlt
zhujinliang
2020-11-06 16:43:40 +08:00
肯定先画大图然后缩放效率不行,而且图像会模糊
,应建立跟显示界面大小一样的缓冲区,使用数学计算进行坐标的缩放,根据缩放后的坐标绘制到缓冲区,最后 bitblt 到前台
再不行就看看 SVG 方面有没有现成的东西

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/722397

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX