使用UpdateLayeredWindow做桌面歌词,发现GetHbitmap(Color)效率太低,新手求帮助

小红帽A_A 2013-03-03 06:08:47







桌面歌词需要实时更新,所以需要实时调用UpdateLayeredWindow函数画透明界面。timer是40毫秒,但是做好之后发现CPU使用率偏高,比酷狗,千千静听高太多了,奇怪了。使用性能分析发现是主要是GetHbitmap(Color)这个方法的问题。想打算用C++把SetBits(bitmap bitmap)封装一个dll来使用,不知道能否提升性能。 但是没学过C++没能成功。

本想再做个频谱,但是这样的效率。。。

希望高手能给点帮助!!!
...全文
825 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 30 楼 dylike 的回复:
我现在的任何一个窗口都是updatelayeredwindow,而且都是动态的。
求分享- -。
dylike 2013-04-20
  • 打赏
  • 举报
回复
我现在的任何一个窗口都是updatelayeredwindow,而且都是动态的。
mrsupersky 2013-04-20
  • 打赏
  • 举报
回复
引用 28 楼 dylike 的回复:
引用 26 楼 shigaofei1 的回复:引用 13 楼 dylike 的回复:1 迅雷不是用的.NET,所以不是边解释边编译,没有中间复杂的转换过程 2 迅雷虽然也用updatelayeredwindow,但图像创建部分是Directx 3 updatelayeredwindow本身的效率是高的,慢是慢在GDI+上和.NET代码的托管处理上. 别瞎说了。。。。……
3 updatelayeredwindow本身的效率是高的,慢是慢在GDI+上和.NET代码的托管处理上. 我上面说的主要是针对这句话。。。。 你可以试试用Vc 调用updatelayeredwindow 函数看看,效率有多高。。。
dylike 2013-04-15
  • 打赏
  • 举报
回复
引用 26 楼 shigaofei1 的回复:
引用 13 楼 dylike 的回复:1 迅雷不是用的.NET,所以不是边解释边编译,没有中间复杂的转换过程 2 迅雷虽然也用updatelayeredwindow,但图像创建部分是Directx 3 updatelayeredwindow本身的效率是高的,慢是慢在GDI+上和.NET代码的托管处理上. 别瞎说了。。。。别误导群主。。。
好的,误导群主了,抱歉,当我没说。
mrsupersky 2013-04-15
  • 打赏
  • 举报
回复
LZ的桌面歌词 显然 比酷狗的,面积要大很多吧。。。 当然迅雷怎么弄的我确实还不是很清楚。。。。
mrsupersky 2013-04-15
  • 打赏
  • 举报
回复
引用 13 楼 dylike 的回复:
1 迅雷不是用的.NET,所以不是边解释边编译,没有中间复杂的转换过程 2 迅雷虽然也用updatelayeredwindow,但图像创建部分是Directx 3 updatelayeredwindow本身的效率是高的,慢是慢在GDI+上和.NET代码的托管处理上.
别瞎说了。。。。别误导群主。。。
ttsping 2013-04-08
  • 打赏
  • 举报
回复
先PS,lz的代码好像和有个桌面金鱼的一样。。 貌似GDI+中那个函数效率不高,自己写个替换试试: 以下摘抄自FOOBAR插件wsh mod
    HBITMAP create_hbitmap_from_gdiplus_bitmap(Gdiplus::Bitmap * bitmap_ptr)
    {
        BITMAP bm;
        Gdiplus::Rect rect;
        Gdiplus::BitmapData bmpdata;
        HBITMAP hBitmap;

        rect.X = rect.Y = 0;
        rect.Width = bitmap_ptr->GetWidth();
        rect.Height = bitmap_ptr->GetHeight();

        if (bitmap_ptr->LockBits(&rect, Gdiplus::ImageLockModeRead, PixelFormat32bppPARGB, &bmpdata) != Gdiplus::Ok)
        {
            // Error
            return NULL;
        }

        bm.bmType       = 0;
        bm.bmWidth      = bmpdata.Width;
        bm.bmHeight     = bmpdata.Height;
        bm.bmWidthBytes = bmpdata.Stride;
        bm.bmPlanes     = 1;
        bm.bmBitsPixel  = 32;
        bm.bmBits       = bmpdata.Scan0;

        hBitmap = CreateBitmapIndirect(&bm);
        bitmap_ptr->UnlockBits(&bmpdata);
        return hBitmap;
    }
summer_insects 2013-04-03
  • 打赏
  • 举报
回复
按楼主在19楼的提示,我倒是实现出跟酷狗差不多的效果了 也是40MS一刷新,也是用的UpdateLayeredWindow,基本上不占CPU 不知道为什么你的会那么占CPU
summer_insects 2013-03-11
  • 打赏
  • 举报
回复
PS:我用XueTr看了,酷狗的没有加载gdiplus.dll
laviewpbt 2013-03-11
  • 打赏
  • 举报
回复
GetHbitmap实际是调用的GdipCreateHBITMAPFromBitmap函数,这个函数会重新创建一个图像的,然后再把Bitmap的数据拷贝到HBITMAP中,看楼主下面的代码,应该是想调用AlphaBlend来显示PNG图像,由于AlphaBlend需要PARGB的数据才能正确显示PNG,楼主应该还要做个ARGB-->的转换过程,这个速度就还不如GDI+的DrawImage了。 如果楼主的图像大小固定并且一定要使用AlphaBlend函数,我的方案是先创建好一副32位的DIBSECTION,然后每次要处理时,用GDI+的Lockbits 配合 ImageLockMode.UserInputBuffer 以及 PixelFormat.Format32bppPArgb参数 将数据写入DIBSECTION的内存中,在显示。
summer_insects 2013-03-11
  • 打赏
  • 举报
回复
楼主,我用C写了个DLL,可以用来解KRC歌词,你要的话给个邮箱

另外我也想做桌面歌词,只是锯齿问题不知道怎么解决,
我仔细看了酷狗的
截了张图

注意到,当黑色字遇到白色背景时,它的边缘做了抗锯齿
而黑色字遇到黑色背景,则什么都看不见
而,白色字遇到白色背景时,边缘有勾连,而且也做了抗锯齿
白色字遇到黑色背景,同样也有边缘抗锯齿
想了几天都不知道这个效果是怎么实现的
小红帽A_A 2013-03-11
  • 打赏
  • 举报
回复
引用 22 楼 lllanm 的回复:
楼主 你那个资源样本占用 用的是什么工具 可以介绍一下么
就是VS2010自带的性能分析工具!
lllanm 2013-03-11
  • 打赏
  • 举报
回复
楼主 你那个资源样本占用 用的是什么工具 可以介绍一下么
summer_insects 2013-03-11
  • 打赏
  • 举报
回复
引用 19 楼 woshixiaohongmao 的回复:
引用 16 楼 wohaaitinciu 的回复:楼主,我用C写了个DLL,可以用来解KRC歌词,你要的话给个邮箱 另外我也想做桌面歌词,只是锯齿问题不知道怎么解决, 我仔细看了酷狗的 截了张图 注意到,当黑色字遇到白色背景时,它的边缘做了抗锯齿 而黑色字遇到黑色背景,则什么都看不见 而,白色字遇到白色背景时,边缘有勾连,而且也做了抗锯齿 白色字遇到……
但是,我用XueTr看了,酷狗的没有加载gdiplus.dll
小红帽A_A 2013-03-11
  • 打赏
  • 举报
回复
引用 17 楼 laviewpbt 的回复:
GetHbitmap实际是调用的GdipCreateHBITMAPFromBitmap函数,这个函数会重新创建一个图像的,然后再把Bitmap的数据拷贝到HBITMAP中,看楼主下面的代码,应该是想调用AlphaBlend来显示PNG图像,由于AlphaBlend需要PARGB的数据才能正确显示PNG,楼主应该还要做个ARGB-->的转换过程,这个速度就还不如GDI+的D……


我不是使用AlphaBlend函数,AlphaBlend函数不是用来图像混合的吗!而我用的是UpdateLayeredWindow函数来做透明窗体。
调用UpdateLayeredWindow函数的这些代码是来自互联网的,GetHbitmap方法是将GDI+对象转为GDI对象,如果不使用GDI对象能调用UpdateLayeredWindow来实现透明窗体吗?
接着上面的代码:
小红帽A_A 2013-03-11
  • 打赏
  • 举报
回复
引用 16 楼 wohaaitinciu 的回复:
楼主,我用C写了个DLL,可以用来解KRC歌词,你要的话给个邮箱 另外我也想做桌面歌词,只是锯齿问题不知道怎么解决, 我仔细看了酷狗的 截了张图 注意到,当黑色字遇到白色背景时,它的边缘做了抗锯齿 而黑色字遇到黑色背景,则什么都看不见 而,白色字遇到白色背景时,边缘有勾连,而且也做了抗锯齿 白色字遇到黑色背景,同样也有边缘抗锯齿 想了几天都不知道这……
使用GDI+绘图就可以有抗锯齿的效果。 修改绘图对象的平滑模式为抗锯齿。再画路径和填充路径。 g.SmoothingMode = SmoothingMode.AntiAlias;
dylike 2013-03-09
  • 打赏
  • 举报
回复
我是非常热衷层窗体的,但涉及频繁绘制,我不敢用大面积.
dylike 2013-03-09
  • 打赏
  • 举报
回复
1 迅雷不是用的.NET,所以不是边解释边编译,没有中间复杂的转换过程 2 迅雷虽然也用updatelayeredwindow,但图像创建部分是Directx 3 updatelayeredwindow本身的效率是高的,慢是慢在GDI+上和.NET代码的托管处理上.
菜牛 2013-03-09
  • 打赏
  • 举报
回复
你去逐个写点效率可想而知,用剪裁区域直接绘制上去。
Yale_Yange 2013-03-08
  • 打赏
  • 举报
回复
引用 11 楼 woshixiaohongmao 的回复:
引用 10 楼 Grey110 的回复:引用 8 楼 woshixiaohongmao 的回复:引用 5 楼 dylike 的回复:减少绘制面积是提升性能的最好方法。 但是,我就是需要一个大窗体显示歌词啊!但是,迅雷的界面为什么效率那么高啊!还是动态半透明的! 之前我做的仿酷狗歌曲列表,你提示了,绘制需要绘制的部分,我现在也这样建议你 你没用过UpdateL……
是我最近才在网上无意中找到的 java版本的代码,还没来得及翻译成C#的,先给你吧
加载更多回复(11)

110,567

社区成员

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

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

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