VB在picture控件里面画实心圆最快的方法是什么?circle太慢了

wuganxiu 2017-10-29 04:42:16
VB在picture控件里面画实心圆最快的方法是什么?circle太慢了
Picture1.FillColor = RGB(255,0,0)
Picture1.Circle (200, 200, 100, vbBlue
一次性画少一些还行,当一次性要画上万个的时候,速度就非常慢了
有什么可以快速画实心圆的方法没,谢谢
...全文
1546 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
wuganxiu 2017-11-03
  • 打赏
  • 举报
回复
我的09年的机,测试了一下330这样,电脑确实老了
脆皮大雪糕 2017-11-02
  • 打赏
  • 举报
回复
引用 20 楼 ayalicer 的回复:
[quote=引用 17 楼 chewinggum 的回复:] 我这试了一下,1万个圆圈处理在70ms左右,差不多就在15帧左右 设置picturebox 的autoredraw属性效率提升明显。另外看楼主代码scalmode貌似用的是默认的twip建议 用Pixel 下面用的代码,窗体里面放一个picturebox 一个按钮 一个timer即可 用了timer可能会被吐槽,我只是为了省事,可以自己用循环去处理。 另外,如果只是为了界面演示,其实真不介意跳几帧 ...
测试了下 我这边40左右 编译成exe 是30左右[/quote] 应该主要还看CPU,我的测试机是一台5年前的机器。
笨狗先飞 2017-11-01
  • 打赏
  • 举报
回复
感觉楼主在做一个LED屏的编辑器,支持把gif导入到LED控制器里,然后实现一个预览功能。
脆皮大雪糕 2017-11-01
  • 打赏
  • 举报
回复
我这试了一下,1万个圆圈处理在70ms左右,差不多就在15帧左右 设置picturebox 的autoredraw属性效率提升明显。另外看楼主代码scalmode貌似用的是默认的twip建议 用Pixel 下面用的代码,窗体里面放一个picturebox 一个按钮 一个timer即可 用了timer可能会被吐槽,我只是为了省事,可以自己用循环去处理。 另外,如果只是为了界面演示,其实真不介意跳几帧

Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long


Dim r As Double
Const rad = 3.14 / 360
Private Sub Command1_Click()
    Me.ScaleMode = 3
    
    
    Picture1.Width = 500
    Picture1.Height = 500
    Picture1.FillStyle = 0
    
    Picture1.ScaleMode = 3          '这两行是重点
    Picture1.AutoRedraw = True
    
    Timer1.Interval = 1
    Timer1.Enabled = True
   
End Sub

Private Sub Timer1_Timer()
    Dim i As Integer
    Dim j As Integer
    Dim t As Long
    t = GetTickCount
    r = r + 10
    
    For i = 1 To 100
        For j = 1 To 100
            ' 画1万个圈圈,加了点动画免得觉得没动
            Picture1.FillColor = RGB(128 * (Sin((Sqr(i ^ 2 + j ^ 2) + r) * rad * 10) + 1), 128 * (Sin((Sqr(i ^ 2 + j ^ 2) + r + 60) * rad * 10) + 1), 255)
            Picture1.Circle (i * 5, j * 5), 2, vbBlack
        Next
    Next
    Me.Caption = GetTickCount - t '在窗体标题栏显示单次渲染毫秒数,我这里显示在70毫秒以内 刚刚好在15帧左右
End Sub

  • 打赏
  • 举报
回复
引用 17 楼 chewinggum 的回复:
我这试了一下,1万个圆圈处理在70ms左右,差不多就在15帧左右 设置picturebox 的autoredraw属性效率提升明显。另外看楼主代码scalmode貌似用的是默认的twip建议 用Pixel 下面用的代码,窗体里面放一个picturebox 一个按钮 一个timer即可 用了timer可能会被吐槽,我只是为了省事,可以自己用循环去处理。 另外,如果只是为了界面演示,其实真不介意跳几帧 ...
测试了下 我这边40左右 编译成exe 是30左右
wuganxiu 2017-11-01
  • 打赏
  • 举报
回复
谢谢各位老师
wuganxiu 2017-10-31
  • 打赏
  • 举报
回复
好的,我做的东西其实很简单的,我先用GetDIBits函数采集一段视频或者动画的RGB值,然后提取其中1万个点RGB(30k的数据)的像素保存在.bin文件中,这个过程是正确的,速度10万个点每秒可以做到25帧,这里没有问题,采集的过程在Timer1_Timer()r控件里面完成
lrtn = GetDIBits(DC, iBitmap, 0&, iHeight, Bits1(0, 0, 0), bi24BitInfo, 0&)
ReleaseDC 0, DC
Dim r As Integer
Dim g As Integer
Dim b As Integer
''''''''''''''''''''''''''''''''''''''''''''''''''

Dim i4 As Long

For i = 0 To 99
For j = 0 To 99
Bits2(2, i, j) = Bits1(2, a2(i), b2(j)) ‘a2(i),b2(i)就是要采集点的坐标啦
Bits2(1, i, j) = Bits1(1, a2(i), b2(j))
Bits2(0, i, j) = Bits1(0, a2(i), b2(j))
'Bits1(2, i, j) = 255
'Bits1(1, i, j) = 0
'Bits1(0, i, j) = 0
Next j
Next i
'For ix = 0 To ik

Open "d:\1.bin" For Binary As #1
Put #1, k, Bits2
k = k + 30000(每次提取30k的数据,将这30K的数据保存到bin文件中)
Close #1

再者,采集完后,就要查看采集的效果怎么样,所以我就要把上面1.bin文件的数据显示到picture控件里面去
比如说我一共采集1万点,在picture控件上面显示1万个点
Dim Buff(0 to 29999) As Byte' 1万个点30k的数据
Open "d:\1.bin" For Binary As #1 ’打开1.bin文件
For i1 = 1 To 100 ‘采集了100帧,就得刷新100次,读取100次数据
Get #1, wei, Buff '每次提取30K的数据放到Buff中,wei为每次读取的位置,初始值1
wei = wei + 30000
Picture1.Cls
Picture1.Picture = LoadPicture()

For i = 0 To 99
For j = 0 To 99
wei1 = i*j+j ‘计算画的圆与采集的数据对应的坐标
Picture1.FillColor = RGB(Buff(wei1) * 2, Buff(wei1 + 1) * 2, Buff(wei1 + 2) * 2)‘给圆填充颜色
Picture1.Circle (a1(i), b1(j)), 100, vbBlue’画圆
Next j
Next i
Picture1.Picture = Picture1.Image

Next i1
Close #1


现在的的问题就是显示这块刷帧的时候太慢了,几千个点的时候蛮快的,就是Picture1.Circle (a1(i), b1(j)), 100, vbBlue’画圆这里太耗时间,显示几张图片,呵呵




熊孩子开学喽 2017-10-31
  • 打赏
  • 举报
回复
每次上万个实心圆, 每秒15次刷新. 我觉得你还是把你最终需要做的东西给说一下吧, 你这个需求不见得就是合理的.
of123 2017-10-31
  • 打赏
  • 举报
回复
每个圆颜色不同,有一万个。你这一万种颜色是怎么配的?看的人怎么分得清一万种颜色?
threenewbee 2017-10-31
  • 打赏
  • 举报
回复
放在imagelist里,直接贴图
赵4老师 2017-10-31
  • 打赏
  • 举报
回复
首先,没必要画成圆显示,因为实际的像素不是圆。 其次,就算要画成圆显示,也没必要用Circle语句逐个画圆,画一个圆到一幅小的Picture上,再用PaintPicture将小Picture画到大Picture上应比用Circle语句略快。嫌PaintPicture还不够快,还可以改用API BitBlt 最后,窗口中当前看不见的部分当然没必要画了。 另外,请参考这个软件:https://docs.microsoft.com/zh-cn/sysinternals/downloads/zoomit
wuganxiu 2017-10-31
  • 打赏
  • 举报
回复
是的,就是像素点放大显示
  • 打赏
  • 举报
回复
就是像素点放大成一个圆显示
wuganxiu 2017-10-30
  • 打赏
  • 举报
回复
我的每个圆的颜色是不同的,而且要实时更新的,比如1秒钟更新15次这样,1万个圆都得更新的
of123 2017-10-30
  • 打赏
  • 举报
回复
实际上,图片就是一个个像素的状态。采用画圆和填充的方式,是要实时对生成的像素进行计算处理,而且计算了两轮(画圆和填充)。如果还要实时改变显示,则更慢。 采用现成的实心圆,等于事先准备好了像素矩阵,直接贴进去。 处理过程中,最好将 Picture 控件设置为 visible = False。
of123 2017-10-30
  • 打赏
  • 举报
回复
事先用 ImageList 控件保存内含不同直径实心圆的正方形图片(最好各边与圆相切,便于确定位置),用 PaintPicture 方法复制到 Picture 控件中。
脆皮大雪糕 2017-10-30
  • 打赏
  • 举报
回复
这种需求根本就不需要考虑技术实现,根本就是伪需求,你即使用DX或OpenGL啥的搞定了,用的人看一眼也就叫你改了,根本没法用。劝你先确认需求。
脆皮大雪糕 2017-10-30
  • 打赏
  • 举报
回复
就几个问题:这么多圆圈,这么高的刷新率,给特么谁看的?他会数你每个圈圈刷新几次么?少画几个圈圈,少刷新几次他看得出来么?你给他那么多圈圈他分得清楚哪个是哪个么?那一万多个圈圈圈的场景给他看过么?他骂你了没有?
赵4老师 2017-10-30
  • 打赏
  • 举报
回复
1秒钟更新15次这样,1万个圆都得更新的?! 给谁看? 谁又能看得清? 你说你“1秒钟更新15次,1万个圆都更新”;我说你“1秒钟更新仅10次,1万个圆只更新了1000个”。谁来证明你对还是我对?怎么证明? 牛皮只适合用来吹吹。当真就钻牛角尖了。
wuganxiu 2017-10-30
  • 打赏
  • 举报
回复
我想做一个采集GIF图片的像素,比如说采集1万个像素点,然后把这1万个像素点显示到picture里面,显示的时候像素点不能太小,并且显示的速度要跟上GIF图像变化的速度,也就是一边采集一边显示,基本要与GIF变化同步,采集可以用GetDIBits,然后再提取想要像素的坐标,就是显示这块,用picture.circle太慢了,阁下有什么好的建议吗,谢谢
加载更多回复(2)
Option Explicit Const Pi = 3.1415926 Public b As Integer Dim p() As Single, q() As Single Private Sub Timer1_Timer() Text1 = Rnd * 201 + 100 '生成随机数 Text2 = Rnd * 101 + 20 b = b + 1 ReDim Preserve p(b) '定义两个一维数组用以保存生成的随机树 ReDim Preserve q(b) p(b) = Val(Text1) q(b) = Val(Text2) Shpblue.Height = Text1 * 7 '改变蓝色控件的高度模拟反应釜内液面变化 Shpblue.Top = 2200 + 5880 - Text1 * 7 If b Mod 50 = 0 And b >= 50 Then '在图片框控件出对应的曲线 Picture1.Cls Else Picture1.Line (80 * (b Mod 50 - 1), 3000 - p(b - 1) * 10)-(80 * (b Mod 50), 3000 - p(b) * 10), &HFF Picture1.Line (80 * (b Mod 50 - 1), 3000 - q(b - 1) * 10)-(80 * (b Mod 50), 3000 - q(b) * 10), &HFF0000 End If End Sub Private Sub Text1_Change() Dim a As String * 20, c As String * 20 Open "D:\bjz.txt" For Input As #1 Line Input #1, a Line Input #1, c If Val(Text1.Text) > a Then Label3.Caption = "液位超上限" Else: Label3.Caption = "" End If Close #1 End Sub Private Sub Text2_Change() Dim e As String * 20, f As String * 20 Open "D:\bjz.TXT" For Input As #1 Line Input #1, e Line Input #1, f If Val(Text2.Text) > f Then Label4.Caption = "温度超上限" Else: Label4.Caption = "" End If Close #1 End Sub Private Sub cmd1_Click() Form2.Show '窗体2出现 End Sub Private Sub cmd2_Click() Dim m As Integer Open "d:\data.txt" For Output As #2 '保存数据 Print #2, "时间(s), 温度(℃), 液体(cm)" Close #2 For m = 1 To b Open "D:\data.txt" For Append As #3 Write #3, m, p(m), q(m) Close #3 Next End Sub Private Sub cmd3_Click() End '结束程序 End Sub Private Sub Form_Activate() Circle (3340, 8080), 700, vbBlue, -Pi, -2 * Pi ' Circle (3340, 5880), 700, vbRed, -2 * Pi, -Pi End Sub

7,765

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧