图像复制的问题

xxgclj 2013-02-18 10:21:36
想做个类似录音机的程序,上面有左移的波形、频谱图。开始时用SetPixel实现,但是速度太慢,加上内存锁定也慢,后来用Clone实现,速度提高了不少,但是又发现了新问题。

程序电脑不能上网,代码简介如下:

我是在picturebox上绘图,picturebox.image = bmpWaterfall。先把bmpWaterafll右边图像(除去最左边1列像素的图像)clone给bmpTemp,再picturebox.drawImage(bmpTemp, rc),即在picturebox上图像左移1像素,再更新最右边一列像素。

运行正常,速度快,CPU占用率1%以下。但是我当我调整picturebox大小时会发现,当它大过了一个临界值时,CPU占用率会突升到20-30%,不知道怎么回事。我拿以前用C++写的程序看了下,即使全屏了CPU占用率也不会上升多少,很奇怪。

用C#写是因为要给别人做个控件,以前用C++ Builder,别人不方便调用。

希望这方面有经验的朋友帮看下问题何在。
...全文
210 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
xxgclj 2014-03-13
  • 打赏
  • 举报
回复
以前此程序内存增长过快,自己在每次绘制时都进行了垃圾回收,最近无意中把垃圾回收注释掉,意外发现CPU占用率大大降低.
xxgclj 2013-04-02
  • 打赏
  • 举报
回复
有人研究过没?
xxgclj 2013-02-22
  • 打赏
  • 举报
回复
我看了,他用的指针法和我以前用的是一样的。网上有资料研究,指针法比内存法能有近一倍的速度提升,我测试过也是速度提升有限,当然了都比直接像素法速度快不少。但是就实现我的要求来看,目前试过的还是clone最快。clone唯一的缺点就是得新建一个图像,如果能原图内部实现各部分复制就好了(以前C++里可以这样调用,当然了内部实现上是不是这样不清楚)。 C#图片处理常见方法性能比较 http://www.cnblogs.com/sndnnlfhvk/archive/2012/02/27/2370643.html
xxgclj 2013-02-21
  • 打赏
  • 举报
回复
引用 9 楼 Trent1985 的回复:
不是这样的,内存法就是把图像信息从内存中拷贝到数组中进行处理,处理完后在从数组中拷贝到内存中去; 指针法不需要数组进行拷贝,而至用指针直接指向内存中的图像信息,对其进行操纵,这样它省去了向数组拷贝的过程,效率当然不一样了。
不好意思,除了"byte* p = (byte*)bmData.Scan0;"外,我不知道还有哪种可以用指针指向图像的方法,能说明一下吗?
Trent1985 2013-02-21
  • 打赏
  • 举报
回复
你看这个吧,http://dongtingyueh.blog.163.com/blog/#m=0 ,这个上面的C#图像处理部分都是用的指针法,你好好看看方法就明白了。。。。。
Trent1985 2013-02-20
  • 打赏
  • 举报
回复
不是这样的,内存法就是把图像信息从内存中拷贝到数组中进行处理,处理完后在从数组中拷贝到内存中去; 指针法不需要数组进行拷贝,而至用指针直接指向内存中的图像信息,对其进行操纵,这样它省去了向数组拷贝的过程,效率当然不一样了。
xxgclj 2013-02-20
  • 打赏
  • 举报
回复
我在想用内存法或指针法时按行操作比较快,而按列操作时,来回寻址是不是降低速度的原因啊。
xxgclj 2013-02-20
  • 打赏
  • 举报
回复
引用 6 楼 Trent1985 的回复:
引用 5 楼 xxgclj 的回复:引用 4 楼 Trent1985 的回复:对于2,我的意思是你只对一张图像的信息进行处理,不需要处理一列就在clone一次,这样速度肯定慢; 对于3,C#做图像处理有三种方法:1,像素法,就是你的那个setpixel方法,这种最慢;2,内存法,是把图像信息从内存中clone到数组中进行处理,然后在复制到内存中去,速度比像素法快的多,但……
不好意思,我现在理解的指针法就是内存法做的改进,即把"IntPtr ptr = bmData.Scan0;"改为"byte* p = (byte*)bmData.Scan0;"。至于指向每一列,我不太清楚,能详解否?
Trent1985 2013-02-19
  • 打赏
  • 举报
回复
引用 5 楼 xxgclj 的回复:
引用 4 楼 Trent1985 的回复:对于2,我的意思是你只对一张图像的信息进行处理,不需要处理一列就在clone一次,这样速度肯定慢; 对于3,C#做图像处理有三种方法:1,像素法,就是你的那个setpixel方法,这种最慢;2,内存法,是把图像信息从内存中clone到数组中进行处理,然后在复制到内存中去,速度比像素法快的多,但是对于较大图像,仍然比指针法慢;3,……
内存法不可能比指针法快的,这个你可以百度一下,图像越大,指针法的效果越明显;还有,我说的意思是你用指针法,指针指向你要处理的每一列进行处理,不需要进行clone,这个你可能理解错了,在想一下!
xxgclj 2013-02-18
  • 打赏
  • 举报
回复
引用 4 楼 Trent1985 的回复:
对于2,我的意思是你只对一张图像的信息进行处理,不需要处理一列就在clone一次,这样速度肯定慢; 对于3,C#做图像处理有三种方法:1,像素法,就是你的那个setpixel方法,这种最慢;2,内存法,是把图像信息从内存中clone到数组中进行处理,然后在复制到内存中去,速度比像素法快的多,但是对于较大图像,仍然比指针法慢;3,指针法,是用指针直接操作内存,速度可以比内……
第2条就得一列处理一次啊,如果几列处理一次,移动就不平滑了,成跳着走了。 第3条我曾经试过,我记得比内存法快不太多,而且比用clone慢。
  • 打赏
  • 举报
回复
没试过。。帮你顶下吧。
Trent1985 2013-02-18
  • 打赏
  • 举报
回复
对于2,我的意思是你只对一张图像的信息进行处理,不需要处理一列就在clone一次,这样速度肯定慢; 对于3,C#做图像处理有三种方法:1,像素法,就是你的那个setpixel方法,这种最慢;2,内存法,是把图像信息从内存中clone到数组中进行处理,然后在复制到内存中去,速度比像素法快的多,但是对于较大图像,仍然比指针法慢;3,指针法,是用指针直接操作内存,速度可以比内存法快一个数量级以上,给你个博客,可以看一下,有内存法也有指针法http://dongtingyueh.blog.163.com/blog/#m=0
xxgclj 2013-02-18
  • 打赏
  • 举报
回复
引用 2 楼 Trent1985 的回复:
1,winform中picturebox是很耗内存的,所以微软发布了wpf,用它里面的Image控件会好很多; 2,你不需要处理一次就clone一次,只需要对一张图像多次处理,然后赋值给picturebox即可; 3,使用指针操作,不要用内存法;
感谢回复,第2、3条没明白。能详解否?
Trent1985 2013-02-18
  • 打赏
  • 举报
回复
1,winform中picturebox是很耗内存的,所以微软发布了wpf,用它里面的Image控件会好很多; 2,你不需要处理一次就clone一次,只需要对一张图像多次处理,然后赋值给picturebox即可; 3,使用指针操作,不要用内存法;

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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