仿酷狗音乐播放器开发日志二十一 开发动态调色板控件(附源代码)
转载请说明原出处,谢谢~~
上一篇仿酷狗日志结束后,整个换肤功能就仅仅剩下调色板功能没有做了。我本以为会非常easy。可是研究了酷狗的调色板功能后发现不是那么简单的事情。首先看一下酷狗的调色板的样子:
我原本以为酷狗的主界面仅仅是一张图片。然后通过鼠标坐标来选择颜色,简单粗暴。
等我開始做这部分时发现情况不一样。
能够看到,酷狗的调色板分为两部分,上半部分是调色板的主界面,下半部分是调整亮度的工具栏,我这里分别给他们起名为Pallet和Bar方便说明。这个调色板的Pallet部分的总体亮度能够依据Bar的值而改变,而Bar的颜色会依据Pallet的选择的颜色而改变,这就加大了难度。
这个调色板动态生成了颜色值。假设要做出一样的功能,首先要解决的就是得知这个调色板的绘制算法,这个着实让我头疼,由于我曾经从来没有研究过调色板,也不喜欢搞这样的算法。
我首先对不同亮度下的酷狗调色板截图,然后放到PS中。打开ps的调色板后对图片上的各个颜色取色来研究他们的规律。
总算有些发现,这个大家最好自己实践一下:
在PS中有多重画图模式:RGB、HSB、CMYK、LAB。測试了几个图片后。发现这个调色板的图片能够从HSB模式发现规律。大致的规律是:在一行中向右取色,HSB三个值中仅仅有H的值变化。在一列中。从上往下取色,S值变大、B值变小。并且S值在达到图片的中间部分后再往下就不会增大,我把它称作S的临界值,而图片亮度越低,S的临界值就越小!而B值变小的速度是总体越来越快。
在CodeProject中查了几个资料和demo后,对画图的方式有了一些了解。
首先我补充一下HSB的知识,具体资料请自行百度:
在HSB模式中,H(hues)表示色相。S(saturation)表示饱和度。B(brightness)表示亮度。 HSB模式相应的媒介是人眼。
在通常的使用中,色相是由颜色名称标识的,比方红、绿或橙色。黑色和白色无色相。
白、黑和其它灰色色彩都没有饱和度的。在最大饱和度时,每一色相具有最纯的色光。
取值范围0~100%。
取值范围0~100%。
HSB模式中S和B呈现的数值越高。饱和度明度越高。页面色彩强烈艳丽。对视觉刺激是迅速的,醒目的效果,但不易于长时间的观看。以上两种颜色的S数值接近,是强烈的状态。H显示的度是代表在色轮表里某个角度所呈现的 色相 状态,相对于SB来说,意义不大。
了解了HSB的意思后,首先要知道RGB与HSB的转换算法。由于在duilib中才用RGB的画图模式。这里给出基本的转换算法(部分算法并不是我写的而是摘自网络):
struct RGBColor{int r;int g;int b;RGBColor():r(0),g(0),b(0){}
};struct HSBColor{int h;int s;int b;HSBColor():h(0),s(0),b(0){}
};
COLORREF CPalletUI::GetColorFromHSB(int h,int s, int b)
{COLORREF color;double H = h;double B = (double)b / 100;double S = (double)s / 100;double rgbR,rgbG,rgbB;H = (H >= 360) ?
0 : H ; if(S == 0) { rgbR = B * 255; rgbG = B * 255; rgbB = B * 255; } else { int i = ((int)floor((double)H / 60)) % 6; double f = H / 60 - i; double p = B * (1 - S); double q = B * (1 - S * f); double t = B * (1 - S * (1 - f)); switch(i) { case 0: rgbR = B, rgbG = t, rgbB = p; break; case 1: rgbR = q; rgbG = B; rgbB = p; break; case 2: rgbR = p; rgbG = B; rgbB = t; break; case 3: rgbR = p; rgbG = q; rgbB = B; break; case 4: rgbR = t; rgbG = p; rgbB = B; break; case 5: rgbR = B; rgbG = p; rgbB = q; break; } rgbR = rgbR * 255; rgbG = rgbG * 255; rgbB = rgbB * 255; } color = RGB(rgbR + 0.5,rgbG + 0.5,rgbB + 0.5); return color; }
HSBColor CPalletUI::GetHSBFromColor(COLORREF color)
{HSBColor hsb;RGBColor rgb = GetRGBFromColor(color);double R = rgb.r, G = rgb.g, B = rgb.b;double var_Min = min(min(R, G), B); double var_Max = max(max(R, G), B); double hsbH,hsbS,hsbB;if(var_Min == var_Max) { hsbH = 0; } else if(var_Max == R && G >= B) { hsbH = 60 * ( (G - B) / (var_Max - var_Min) ); } else if(var_Max == R && G < B) { hsbH = 60 * ( (G - B) / (var_Max - var_Min) ) + 360; } else if(var_Max == G) { hsbH = 60 * ( (B - R) / (var_Max - var_Min) ) + 120; } else if(var_Max == B) { hsbH = 60 * ( (R - G) / (var_Max - var_Min) ) + 240; } if(var_Max == 0) { hsbS = 0; } else { hsbS = 1 - (var_Min / var_Max); } double var_R = (R / 255); double var_G = (G / 255); double var_B = (B / 255); hsbB = max(max(var_R, var_G), var_B); hsbH = (hsbH >= 360) ? 0 : hsbH; hsb.h = hsbH + 0.5;hsb.s = hsbS * 100 + 0.5;hsb.b = hsbB * 100 + 0.5;return hsb; }
算法描写叙述:
1)依据HSB的概念,我在设计这个动态调色板的绘制算法时,H取值范围为0~360、S和B取值范围0~100。
2)整张图片从左到右的H值从0到360均匀变化。
3)S的初值为0,取S的临界值为总体图片的亮度值(这个值由下方的Bar来确定)。在每一列中,取中间位置为S的临界值所在位置;在上半部分中。S的值均匀增大。下半部分中。S的值一直取临界值
4)B的初值为100。在每一列中,B的值总是趁减小趋势,减小的速度越来越快。原酷狗的B的临界值会依据图片亮度的变化而改变位置。我这里做了简化,让B的临界值位置在中间,而取B的临界值的算法为 100 - (100 - 总体亮度)/ 2。
通过观察得知整张图片分为上下两部分,去其高度为200,所以每部分高度为100。
c++的描写叙述代码为:
//m_nCurB为图片总体的亮度值,由Bar决定
int SValue = m_nCurB; //取S的临界值为图片总体的亮度
int BValueTop = (100 - SValue)/2; //取B的临界值为100 - (100 - 总体亮度)/ 2
int BValueBottom = 100 - BValueTop;for(int i = 0; i < 100; ++i){ //i表示行数,因为总体高度为200,所以一次性绘制上下两部分的两行for(int j = 0; j < 360; ++j){ //j表示列数int BValue = (100 - i ) * BValueTop / 100 + BValueBottom;COLORREF color = GetColorFromHSB(j,(int)((double)(i * SValue / 100)),BValue);SetPixel(m_MemDc, m_rcItem.left + j,m_rcItem.top + i, color); BValue = i * BValueBottom / 100;color = GetColorFromHSB(j,SValue,BValue);SetPixel(m_MemDc, m_rcItem.left + j,m_rcItem.top + 199 - i, color); }
}
以上是调色板主界面的绘制算法。还有剩下的Bar的绘制算法,这个比較简单。Bar的总体颜色的H和S值是通过Pallet部分获取的,剩下的就是从左到右指定不同的B值就能够了。详见源代码。
这个算法弄好后,剩下的就是将其封装为duilib的调色板控件,我继承了CControlUI控件,重写了DoInit()、DoEvent()、DoPaint()函数。
为了让控件在用户点击了Pallet或者Bar的一部分后能够动态变化,须要在DoEvent函数中处理WM_LBUTTONDOWN、WM_LBUTTONUP、WM_MOUSEMOVE消息。先设置两个标记变量,表示鼠标是否在Pallet或者Bar中
1)当用户单击控件的界面时,推断鼠标是否在Pallet或者Bar中。假设在,就设置对应的标记变量为真,用于WM_MOUSEMOVE中继续处理。
2)当用户松开鼠标时,设置标记变量都为假。
3)当用户在控件上移动时,推断是否在Pallet或者Bar中,然后处理对应的消息。假设在Pallet中,依据鼠标坐标动态算出鼠标所在位置的颜色值,用来设置bar的颜色。
假设在Bar中。依据鼠标坐标计算整张图片的亮度值。用来设置Pallet的亮度值。
调色板控件的封装:
核心的算法我米描写叙述完了,剩下仅仅是用c++代码描写叙述一下。我将封装控件命名为CPalletUI,为了设置了两个属性。名为palletheight和barheight,用于设置Pallet的高度和Bar的高度。建议将Pallet的高度设置为200的整数,否则终于效果图easy出现失真。Pallet和Bar的宽度为整个控件的宽度。
另外为控件封装了名为GetSelectColor的函数,用来获取用户终于选择的颜色。
给出一个使用控件的xml描写叙述代码:
<VerticalLayout height="230"><!-- 主体 --><Pallet name="Pallet" width="506" height="220" palletheight="200" barheight="14" padding="7,5,0,0" bkcolor="#FFFFFFFF" />
</VerticalLayout>
在头文件里我写好了常量来表示控件的类名和接口名。方便使用者编写CreateControl函数。
最后给出我模仿酷狗调色板的效果图:
总结:
我个人不擅长算法和图像处理。所以终于的控件的代码质量可能不好。假设哪位朋友有更好的算法、资料或、建议或者发现什么错误,请联系我,不胜感激。
在这个控件编写后几天,网友“风之羽翼”在我原代码基础上,使用新的更合理的代码重写了控件,大幅提升了新控件的性能,在此表示感谢。
新控件的博文地址为:《仿酷狗音乐播放器开发日志二十二 动态调色板控件第二版(性能大幅提升附源代码)》,原控件下载地址就不提供了,大家直接用新的。
Redrain 2014.8.16
转载于:https://www.cnblogs.com/lcchuguo/p/5204485.html
仿酷狗音乐播放器开发日志二十一 开发动态调色板控件(附源代码)相关推荐
- 基于Qt的仿酷狗音乐播放器设计(二)
简述 在上一文"基于Qt的仿酷狗音乐播放器设计(一)"中,博主给出了仿酷狗界面的部分内容,在本文中将继续分析酷狗界面,并作出相应的分析. 下面我们来看一下酷狗界面中的左侧滑动页控制 ...
- 仿酷狗音乐播放器开发日志二十二 动态调色板控件第二版(性能大幅提升附源码)...
转载请说明原出处,谢谢~~ 在上次写的博客<仿酷狗音乐播放器开发日志二十一 开发动态调色板控件(附源码)>发布后,我在群里和网友讨论这个控件的性能和优 缺点,发现了他很多不足,还有很多提升 ...
- 仿酷狗音乐播放器开发日志——整体框架分析
转载请说明出处,谢谢~~ 学习duilib界面库有一段时间了,除了仓鼠软件共享以外还没用它开发过什么完整的软件项目.今天看到酷狗音乐播放器做得不错,经过几年的改革,酷狗现在的UI已经相当不错了.在这个 ...
- 仿酷狗音乐播放器开发日志二十一 开发动态调色板控件(附源码)
转载请说明原出处,谢谢~~ 上一篇仿酷狗日志结束后,整个换肤功能就只剩下调色板功能没有做了,我本以为会很简单,但是研究了酷狗的调色板功能后发现不是那么简单的事情.首先看一下酷狗的调色板的样子: 我原本 ...
- 仿酷狗音乐播放器开发日志十四——右侧乐库的实现
在使用酷狗播放器时,左侧功能块和右侧乐库功能是最常用的了,如果要下载音乐或者搜索自己喜欢的歌曲那就少不了右侧乐库.原版的乐库的截图如下 他拥有5个分类,分别是乐库.电台.MV.直播.歌词.从外 ...
- 【游戏开发创新】手把手教你使用Unity制作一个高仿酷狗音乐播放器,滨崎步,旋律起,爷青回(声音可视化 | 频谱 | Audio)
文章目录 一.前言 二.获取UI素材 三.使用UGUI制作界面 1.界面布局 2.账号圆形头像 3.搜索框 4.调节UI层 5.黑色按钮悬浮高亮效果 6.纯文字按钮 7.滚动列表自适应 8.歌名与视频 ...
- 仿酷狗音乐播放器已开源!
转载请说明原出处,谢谢:http://blog.csdn.net/zhuhongshu/article/details/41037875 距离我发布测试版的Redrain音乐盒(仿酷狗播放器),现在正 ...
- android高仿酷狗音乐播放器源码下载
这是一款简单的读取SD卡音乐文件进行播放.暂停.删除.切歌等功能的高仿酷狗音乐播放器. 主要功能: 模块 简要说明 扫描SD卡音乐 扫描SD卡,并显示出本地音乐列表 提供歌词跟随音乐滚动更能 采用 ...
- 关于仿酷狗音乐播放器开源:寻求一套音乐播放器素材,让仿酷狗开源
转载请说明原出处,谢谢~~ 距离公布測试版的仿酷狗音乐播放器.已经几个月过去了.期间非常多网友加我QQ来问我开源的问题,我也早有开源意向. 但我也一直没有得到可靠的信息,保证开源后没有不论什么问题. ...
最新文章
- 最后一场「屏之争」:汽车大佬与硅谷巨头的贴身肉搏
- JZOJ 3.10 1540——岛屿
- bzoj 3055礼物运送 floyed + 状压DP
- 多个圆点,鼠标选取两个,求两个点的距离,用于计算像素尺寸(halcon实现)
- 微软分拆小冰业务并独立发展,沈向洋任董事长
- 数据库名、实例名、数据库域名、全局数据库名、服务名 ,
- 用opencv在图片上面添加水印
- Linux命令行下,颜色表示什么意思
- memcmp函数使用详解
- 谷粒微博学习笔记一:Utilsconstants
- jstack 工具 查看JVM堆栈信息
- 私删手机照片?豆瓣道歉了
- 避雷秘籍:iOS过审的基础条件
- C++: 函数重载(c++函数原型、函数重载要素)
- 如何使用CAD编辑器来画箭头
- 考研英语 常见介词词组
- Vue点击按钮下载对应图片
- 车牌字符识别OCR算法评估
- 纸的大小图解_常用纸张尺寸及示意图(A0,A1...A3,A4,A5...
- 爬虫案例——中超联赛新闻