V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iSNN
V2EX  ›  程序员

求教 C# 绘图问题

  •  
  •   iSNN · 81 天前 · 1054 次点击
    这是一个创建于 81 天前的主题,其中的信息可能已经有所发展或是发生改变。

    老师给的一个课题:

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

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

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

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

    29 条回复    2020-11-13 13:59:34 +08:00
    GM
        1
    GM   81 天前
    这问题,看得头皮发麻。。。。。


    “GIS 那样的”是怎样?

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

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


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

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

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

    其他的手画遇到 hidpi 缩放就跪了啊。。。
    GM
        22
    GM   81 天前
    @iSNN 那当然了,图片缩放很慢的,慢得惨无人寰。想要快,事先准备好各种比例的图片,直接 draw 上去,别缩放。
    binsys
        23
    binsys   80 天前
    CefSharp(或 CefGlue) 壳,跑 HTML 版本的 Leaflet openlayers d3 等,在 Leaflet openlayers 上做。
    iSNN
        24
    iSNN   74 天前
    @MinQ 谢谢大佬的指点...这几天学了 WPF 的东西,图基本上是画出来了。但是遇到了个问题,我是用 Shapes 里面的图形去画的,道路就是 Line,信号灯就是 Ellipse......不过这些东西都会有一些其他属性,但是这些类都是 sealed 密封类不能继承。我现在就是把这些无法用 Shapes 表示的属性写个类来存储放在一个数组里,然后把道路啊信号编上 Name,然后根据 Name 去数组匹配.......比如一个事件的监听,从 sender 得到 Name,然后 for 数组找匹配的对象,在根据对象里的属性显示不同的东西。请问大佬有好的解决方案吗
    MinQ
        25
    MinQ   74 天前 via Android
    @iSNN 写个新类继承 shape 呗,把想要的属性加上
    MinQ
        26
    MinQ   74 天前 via Android
    @iSNN 控件同理
    iSNN
        27
    iSNN   74 天前
    @MinQ 我也这样想过...但是那些图形的实现我也是不明白,去 referencesource.microsoft.com 找的代码,发现掉了很多 internal 的东西。那就算了吧,找了下 Dictionary 的效率挺不错的,不用数组了,这样效率应该不慢
    MinQ
        28
    MinQ   74 天前 via Android
    @iSNN extends 下来以后会直接把父类的方法都继承了啊,根本不需要再写一遍
    MinQ
        29
    MinQ   74 天前 via Android
    @MinQ 我 github 上有个 AGVMonitor,你参考一下吧
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3678 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 01:04 · PVG 09:04 · LAX 17:04 · JFK 20:04
    ♥ Do have faith in what you're doing.