C# 高仿腾讯QQ (QQ皮肤颜色滑动调色器)

       《QQ皮肤颜色滑动调色器》这个控件去年时就发到群共享了,但一直没发到博客上去。主要呢就是一个是没时间去写博客,还有就是程序有很多BUG还没完善,比如拖动下面滑动条时不是十分的顺畅,占用CPU资源也很等,但在这里还是发出来,大家自己去改善吧!

201103221042260158.jpg
201103221056424748.jpg 

       这个控件刚开始做时原本是打算通过截取一张QQ滑动调色器的图片做为控件调色板背景颜色的,但后来,无意间在网上看到一个老外写的基于HSL色调(H)的调色板程序,而QQ滑动调色器改变颜色的方法是基于(HSL)饱和度(S)(HSL:HSL色彩模式是工业界的一种颜色标准,是通过对色调(H)、饱和度(S)、亮度(L)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,HSL即是代表色调,饱和度,亮度三个通道的颜色,而饱和度(S)懂PS的人应该很清楚,我也是直接截个图放到PS里,再改变他的饱和度才知道QQ是基于饱和度)来变换颜色的,所以我变偿试着改了改他的程序,让他基于饱和度的调节而变换颜色达到QQ的效果。

      这是在PS里的颜色变换图:

201103221043585538.jpg
201103221044302702.jpg

       控件最主要就是RGB与HSL颜色通道之间的换算,至于算法、原理,我想大家去问问百度大叔、Google大妈理解会来得更容易些,在这里我就不说了,让我说我也说不好,呵呵。

       颜色控件由另两个控件组成,一个是 颜色显示区,我单独做成了一个控件。另一个是滑动模块,也是单独做成了一个控件
    
       还是直接贴源,有兴趣的大家自己研究:

ColorAreaAndSliderUserControl.cs完整控件

 

 
   
1 // 作者:阿龙(Along)
2   // QQ号:646494711
3   // QQ群1:57218890
4   // QQ群2:57219423
5   // 网站: http://www.8timer.com
6   // 博客: http://www.cnblogs.com/Along729/
7   // 声明:未经作者许可,任何人不得发布出售该源码,请尊重别人的劳动成果,谢谢大家支持
8   using System;
9   using System.Collections.Generic;
10   using System.ComponentModel;
11   using System.Drawing;
12   using System.Data;
13   using System.Linq;
14   using System.Text;
15   using System.Windows.Forms;
16   using ColorCustomize.Colors;
17
18   namespace ColorCustomize
19 {
20 public partial class ColorAreaAndSliderUserControl : UserControl
21 {
22 double h, l, s;
23 public ColorAreaAndSliderUserControl()
24 {
25 InitializeComponent();
26 }
27
28 private void colorAreaUserControl1_HueSaturationChanged( object sender, EventArgs e)
29 {
30
31 colorAreaUserControl.GetHueSaturation( out h, out s, out l);
32 colorSliderUserControl.SetHueSaturation(h, s, l);
33
34 }
35
36 private void colorAreaUserControl1_ValueChangedByUser( object sender, EventArgs e)
37 {
38 notifyColorChanged();
39 notifyValueChangedByUser();
40 }
41
42 private void colorSliderUserControl_ValueChanged( object sender, EventArgs e)
43 {
44 double s;
45 colorSliderUserControl.GetHueSaturation( out s);
46 colorAreaUserControl.SetHueSaturation(s);
47
48 }
49
50 private void colorSliderUserControl_ValueChangedByUser( object sender, EventArgs e)
51 {
52 notifyColorChanged();
53 notifyValueChangedByUser();
54
55 }
56
57 /// <summary>
58 /// 当用户发生改变颜色.
59 /// </summary>
60   public event EventHandler ColorChanged;
61
62 /// <summary>
63 /// 值时发生了改变.
64 /// </summary>
65 public event EventHandler ValueChangedByUser;
66
67 private void notifyColorChanged()
68 {
69 if (ColorChanged != null )
70 {
71 ColorChanged( this , EventArgs.Empty);
72 }
73 }
74
75 private void notifyValueChangedByUser()
76 {
77 if (ValueChangedByUser != null )
78 {
79 ValueChangedByUser( this , EventArgs.Empty);
80 }
81 }
82
83 public void setColor(Color color)
84 {
85 RgbColor rgb = ColorConverting.ColorToRgb(color);
86 HslColor hsl = ColorConverting.RgbToHsl(rgb);
87 colorAreaUserControl.SetColor(( double )hsl.Hue,( double )hsl.Saturation,( double )hsl.Light);
88 colorSliderUserControl.SetColorSaturation(( double )hsl.Saturation);
89 }
90 public void GetColor( out Color color)
91 {
92 color = ColorConverting.HslToRgb( new HslColor(h,s,l)).ToColor();
93 }
94 }
95 }

ColorAreaUserControl.cs颜色显示区控件

 
   
1 // 作者:阿龙(Along)
2 // QQ号:646494711
3 // QQ群1:57218890
4 // QQ群2:57219423
5 // 网站: http://www.8timer.com
6 // 博客: http://www.cnblogs.com/Along729/
7 // 声明:未经作者许可,任何人不得发布出售该源码,请尊重别人的劳动成果,谢谢大家支持
8 using System;
9 using System.Collections.Generic;
10 using System.ComponentModel;
11 using System.Drawing;
12 using System.Drawing.Drawing2D;
13 using System.Data;
14 using System.Linq;
15 using System.Text;
16 using System.Windows.Forms;
17 using ColorCustomize.Colors;
18 using System.Threading;
19
20 namespace ColorCustomize
21 {
22 public partial class ColorAreaUserControl : UserControl
23 {
24 private double _h;
25 private double _l;
26 private static double _s = 100 ;
27 private Bitmap _colorBitmap;
28
29 public ColorAreaUserControl()
30 {
31 InitializeComponent();
32 SetStyle(ControlStyles.UserPaint |
33 ControlStyles.DoubleBuffer |
34 ControlStyles.ResizeRedraw |
35 ControlStyles.Selectable |
36 ControlStyles.AllPaintingInWmPaint,
37 true );
38 }
39
40 // public void SetHueSaturation(double h, double l)
41 // {
42 // _h = h;
43 // _l = l;
44 // Invalidate();
45
46 // // notifyHueSaturationChanged();
47 // }
48
49
50 public void SetHueSaturation( double s)
51 {
52 _s = s;
53 Calculate();
54 // ThreadStart threadStart = new ThreadStart(Calculate);
55 // Thread thread = new Thread(threadStart);
56 // thread.Start();
57
58 drawCaret();
59 notifyHueSaturationChanged();
60 }
61 public void Calculate()
62 {
63 _colorBitmap = drawColorBitmap();
64 }
65
66
67
68 public void SetColor( double h, double s, double l)
69 {
70 _h = h;
71 _l = l;
72 _s = s;
73 _colorBitmap = drawColorBitmap();
74 drawCaret();
75 // notifyValueChangedByUser();
76 notifyHueSaturationChanged(); ;
77 }
78
79 public void GetHueSaturation( out double h, out double s, out double l)
80 {
81 h = _h;
82 l = _l;
83 s = _s;
84 }
85
86
87 /// <summary>
88 /// Occurs when the user changed the hue and/or saturation.
89 /// 当用户发生改变色调和/或饱和度
90 /// </summary>
91 public event EventHandler HueSaturationChanged;
92
93 /// <summary>
94 /// Occurs when a value has been changed.
95 /// 值更改时发生事件
96 /// </summary>
97 public event EventHandler ValueChangedByUser;
98
99 private void notifyHueSaturationChanged()
100 {
101 if (HueSaturationChanged != null )
102 {
103 HueSaturationChanged( this , EventArgs.Empty);
104 }
105 }
106
107 private void notifyValueChangedByUser()
108 {
109 if (ValueChangedByUser != null )
110 {
111 ValueChangedByUser( this , EventArgs.Empty);
112 }
113 }
114
115 /// <summary>
116 /// 重绘控件
117 /// </summary>
118 /// <param name="e"></param>
119 protected override void OnPaint(PaintEventArgs e)
120 {
121 base .OnPaint(e);
122 if (_colorBitmap == null )
123 {
124 _colorBitmap = drawColorBitmap();
125 }
126 double facXBmpToScreen = ( double )_colorBitmap.Width / ClientSize.Width;
127 double facYBmpToScreen = ( double )_colorBitmap.Height / ClientSize.Height;
128
129 var sourceRect = new Rectangle(
130 ( int )(facXBmpToScreen * ClientRectangle.Left),
131 ( int )(facYBmpToScreen * ClientRectangle.Top),
132 ( int )(facXBmpToScreen * ClientRectangle.Width),
133 ( int )(facYBmpToScreen * ClientRectangle.Height));
134 // e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
135 e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
136 e.Graphics.DrawImage(
137 _colorBitmap,
138 ClientRectangle,
139 sourceRect,
140 GraphicsUnit.Pixel);
141 drawCaret(e.Graphics);
142 }
143
144 /// <summary>
145 /// 绘制位图的颜色
146 /// </summary>
147 /// <returns></returns>
148 private static Bitmap drawColorBitmap()
149 {
150 const int width = 360 ;
151 const int height = 100 ;
152
153 var bmp = new Bitmap(width, height);
154
155 for ( int y = 0 ; y < height; ++ y)
156 {
157 for ( int x = 0 ; x < width; ++ x)
158 {
159 double h = x;
160 double s = _s; // 饱和度
161 double l = 100 - y;
162
163 Color color = new HslColor(h, s, l).ToColor();
164
165 bmp.SetPixel(x, y, color);
166 }
167 }
168
169 return bmp;
170 }
171
172 /// <summary>
173 /// 绘制移动圆点
174 /// </summary>
175 /// <param name="g"> The g. </param>
176 private void drawCaret(
177 Graphics g)
178 {
179
180 Point p;
181 translateHueSaturationToCaretPosition( out p, _h, _l);
182 g.DrawImage( global ::ColorCustomize.Properties.Resources.colorslider_dragbackground, new Rectangle( new Point(p.X - 6 ,p.Y - 6 ), new Size( 12 , 12 )));
183 }
184
185 private void drawCaret()
186 {
187 Invalidate();
188 }
189
190 /// <summary>
191 /// 返回指定的区域内,移动圆点的位置
192 /// </summary>
193 /// <param name="caretPosition"></param>
194 /// <param name="h"></param>
195 /// <param name="s"></param>
196 private void translateHueSaturationToCaretPosition( out Point caretPosition, double h, double l)
197 {
198 double facXBmpToScreen = 360.0 / ClientSize.Width;
199 double facYBmpToScreen = 100.0 / ClientSize.Height;
200
201 h = Math.Max( 0.0 , h);
202 h = Math.Min( 360.0 , h);
203 l = Math.Max( 0.0 , l);
204 l = Math.Min( 100.0 , l);
205
206 double pX = (h / facXBmpToScreen);
207 double pY = (l / facYBmpToScreen);
208
209 pX = Math.Max( 0 , pX);
210 pX = Math.Min(ClientSize.Width - 1 , pX);
211 pY = Math.Max( 0 , pY);
212 pY = Math.Min(ClientSize.Height - 1 , pY);
213
214 pY = ClientSize.Height - pY;
215
216 caretPosition = new Point(( int )pX, ( int )pY);
217 }
218
219
220 /// <summary>
221 ///
222 /// </summary>
223 /// <param name="caretPosition"></param>
224 /// <param name="h"></param>
225 /// <param name="s"></param>
226 private void translateCaretPositionToHueSaturation( Point caretPosition, out double h, out double l)
227 {
228 double facXBmpToScreen = 360.0 / ClientSize.Width;
229 double facYBmpToScreen = 100.0 / ClientSize.Height;
230
231 Point p = caretPosition;
232
233 p.X = Math.Max( 0 , p.X);
234 p.X = Math.Min(ClientSize.Width - 1 , p.X);
235 p.Y = Math.Max( 0 , p.Y);
236 p.Y = Math.Min(ClientSize.Height - 1 , p.Y);
237
238 p.Y = ClientSize.Height - p.Y;
239
240 h = (p.X * facXBmpToScreen);
241 l = (p.Y * facYBmpToScreen);
242
243 h = Math.Max( 0.0 , h);
244 h = Math.Min( 360.0 , h);
245 l = Math.Max( 0.0 , l);
246 l = Math.Min( 100.0 , l);
247 }
248
249 private void ColorAreaUserControl_MouseMove( object sender, MouseEventArgs e)
250 {
251 if (e.Button == MouseButtons.Left)
252 {
253 translateCaretPositionToHueSaturation(e.Location, out _h, out _l);
254 drawCaret();
255
256 notifyValueChangedByUser();
257 notifyHueSaturationChanged();
258 }
259 }
260
261 private void ColorAreaUserControl_MouseClick( object sender, MouseEventArgs e)
262 {
263 if (e.Button == MouseButtons.Left)
264 {
265 translateCaretPositionToHueSaturation(e.Location, out _h, out _l);
266 drawCaret();
267
268 notifyValueChangedByUser();
269 notifyHueSaturationChanged();
270 }
271 }
272
273 private void ColorAreaUserControl_MouseDown( object sender, MouseEventArgs e)
274 {
275
276 if ( e.Button == MouseButtons.Left )
277 {
278 translateCaretPositionToHueSaturation( e.Location, out _h, out _l );
279 drawCaret();
280
281 notifyValueChangedByUser();
282 notifyHueSaturationChanged();
283 // MessageBox.Show(_arvlue.ToString());
284 }
285 }
286
287 private void ColorAreaUserControl_MouseLeave( object sender, EventArgs e)
288 {
289 drawCaret();
290 }
291
292 }
293 }

 ColorSliderUserControl.cs滑动模块控件

 
   
1 // 作者:阿龙(Along)
2   // QQ号:646494711
3   // QQ群1:57218890
4   // QQ群2:57219423
5   // 网站: http://www.8timer.com
6 // 博客: http://www.cnblogs.com/Along729/
7 // 声明:未经作者许可,任何人不得发布出售该源码,请尊重别人的劳动成果,谢谢大家支持
8 using System;
9 using System.Collections.Generic;
10 using System.ComponentModel;
11 using System.Drawing;
12 using System.Data;
13 using System.Linq;
14 using System.Text;
15 using System.Windows.Forms;
16 using ColorCustomize.Colors;
17 using System.Drawing.Drawing2D;
18
19 namespace ColorCustomize
20 {
21 public partial class ColorSliderUserControl : UserControl
22 {
23 private Bitmap _colorBitmap;
24 private double _h;
25 private double _l;
26 public ColorSliderUserControl()
27 {
28 InitializeComponent();
29 SetStyle(ControlStyles.UserPaint |
30 ControlStyles.DoubleBuffer |
31 ControlStyles.ResizeRedraw |
32 ControlStyles.Selectable |
33 ControlStyles.AllPaintingInWmPaint,
34 true );
35 }
36
37 public void SetHueSaturation( double h, double s, double l)
38 {
39 _h = h;
40 _l = l;
41 _colorBitmap = drawColorBitmap();
42 Invalidate();
43
44 // notifyValueChanged();
45 }
46
47 public void SetColorSaturation( double s)
48 {
49 arrowControl.Location = new Point(( 100 - ( int )s) / 100 * this .Width - 6 , - 1 );
50 _colorBitmap = drawColorBitmap();
51 Invalidate();
52
53 // notifyValueChanged();
54 }
55
56 public void GetHueSaturation( out double s)
57 {
58 s = 100.0 - ( double )(arrowControl.Location.X + 6 ) / ( double ) this .Width * 100 ;
59 }
60
61 /// <summary>
62 /// Occurs when a value has been changed.
63 /// 发生在一个值已更改
64 /// </summary>
65 public event EventHandler ValueChangedByUser;
66
67 /// <summary>
68 /// Occurs when a value has been changed.
69 /// </summary>
70 public event EventHandler ValueChanged;
71
72 private void NotifyValueChangedByUser()
73 {
74 if (ValueChangedByUser != null )
75 {
76 ValueChangedByUser( this , EventArgs.Empty);
77 }
78 }
79
80 private void notifyValueChanged()
81 {
82 if (ValueChanged != null )
83 {
84 ValueChanged( this , EventArgs.Empty);
85 }
86 }
87
88 /// <summary>
89 /// Draws the color bitmap.
90 /// </summary>
91 /// <returns></returns>
92 private Bitmap drawColorBitmap()
93 {
94 const int width = 100 ;
95 const int height = 5 ;
96 double h = _h;
97 double l = _l;
98
99 var bmp = new Bitmap(width, height);
100
101 for ( int x = 0 ; x < width; ++ x)
102 {
103 double s = width - x;
104 Color color = new HslColor(h, s, l).ToColor();
105 for ( int y = 0 ; y < height; ++ y)
106 {
107 bmp.SetPixel(x, y, color);
108 }
109
110 }
111 return bmp;
112 }
113
114 protected override void OnPaint(PaintEventArgs e)
115 {
116 base .OnPaint(e);
117 if (_colorBitmap == null )
118 {
119 _colorBitmap = drawColorBitmap();
120 }
121
122 double facXBmpToScreen = ( double )_colorBitmap.Width / ClientSize.Width;
123 double facYBmpToScreen = ( double )_colorBitmap.Height / ClientSize.Height;
124
125 var sourceRect = new Rectangle(
126 ( int )(facXBmpToScreen * ClientRectangle.Left),
127 ( int )(facYBmpToScreen * ClientRectangle.Top),
128 ( int )(facXBmpToScreen * ClientRectangle.Width),
129 ( int )(facYBmpToScreen * ClientRectangle.Height));
130
131 // e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
132 e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
133 e.Graphics.DrawImage(
134 _colorBitmap,
135 ClientRectangle,
136 sourceRect,
137 GraphicsUnit.Pixel);
138
139 }
140 /// <summary>
141 /// 重新定位的箭头。
142 /// </summary>
143 /// <param name="offsetY"> The offset X. </param>
144 private void repositionArrow( int offsetX)
145 {
146 offsetX = Math.Max( 0 , offsetX);
147 offsetX = Math.Min(ClientSize.Width - 1 , offsetX);
148
149 arrowControl.Location = new Point(
150 offsetX - (arrowControl.Width / 2 ), arrowControl.Location.Y);
151 }
152
153 private void arrowControl_MouseMove( object sender, MouseEventArgs e)
154 {
155 if (e.Button == MouseButtons.Left)
156 {
157 repositionArrow(PointToClient(arrowControl.PointToScreen(e.Location)).X);
158 notifyValueChanged();
159 NotifyValueChangedByUser();
160 }
161
162 }
163
164 private void arrowControl_MouseDown( object sender, MouseEventArgs e)
165 {
166 if (e.Button == MouseButtons.Left)
167 {
168 repositionArrow(PointToClient(arrowControl.PointToScreen(e.Location)).X);
169 notifyValueChanged();
170 NotifyValueChangedByUser();
171 }
172 }
173
174 private void ColorSliderUserControl_MouseDown( object sender, MouseEventArgs e)
175 {
176 if (e.Button == MouseButtons.Left)
177 {
178 repositionArrow(PointToClient( this .PointToScreen(e.Location)).X);
179 notifyValueChanged();
180 NotifyValueChangedByUser();
181 }
182 }
183
184 private void ColorSliderUserControl_MouseMove( object sender, MouseEventArgs e)
185 {
186 if (e.Button == MouseButtons.Left)
187 {
188 repositionArrow(PointToClient( this .PointToScreen(e.Location)).X);
189 notifyValueChanged();
190 NotifyValueChangedByUser();
191 Invalidate();
192 }
193 }
194
195 }
196 }

还有几个颜色换算类在这里不贴了,不然这篇幅也太长了点,大家直接下载源码看吧

源码下载

转载于:https://www.cnblogs.com/Along729/archive/2011/03/22/ColorCustomize.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
源码描述: 一、源码描述 GG是QQ高仿版,包括客户端和服务端,可在广域网部署使用,目前推出的最新版本为4.3。 GG 4.3版本增加的主要功能是:在视频聊天的过程中,随时可以启动录制,录制将把聊天双方的视频图像和双方的声音都录制下来生成一个标准的mp4文件,该mp4文件可用任意的影音播放打开播放。 二、功能介绍 01、注册、登录、查找用户、添加好友、好友列表。 02、自拍头像。 03、文字聊天、字体设置、GIF动态表情、窗口震动、截图、手写板、登录状态(在线、离开、忙碌、勿打扰、隐身)、输入提醒) 04、群功能:创建群、加入群、退出群、群聊天 05、文件传送、文件夹传送(支持断点续传) 06、语音视频聊天 07、远程磁盘 08、远程协助 09、共享桌面(可以指定要共享的桌面区域) 10、可靠的P2P 11、网盘 12、离线消息 13、离线文件 14、托盘闪动:跟QQ完全一样,当接收到消息时,托盘会闪动对应好友的头像。点击头像,将弹出与好友的聊天框。 15、最近联系人列表 16、系统设置:开机自动启动、麦克风设备索引、摄像头设备索引,叉掉主窗口时关闭程序还是隐藏窗口。 17、聊天记录:支持本地保存和服务端保存两种方式。 18、好友分组:新增/删除分组,修改分组名称,改变好友的所属分组。 19、打开聊天窗口时,自动显示上次交谈的最后一句话。 20、输入提醒:像QQ一样,当对方正在输入消息时,我这边的聊天框可以看到对方“正在输入”的提示。 21、自动记录:GG2014会自动记录上次打开的主界面的位置、大小;最后一次打开的聊天窗口的大小;最后一次设定的字体的颜色、大小等。 22、主窗体靠边自动隐藏。 23、录制视频聊天。 三、注意事项 1.当前版本服务端默认配置为内存虚拟数据库版本,不需要安装数据库。 2、开发环境为Visual Studio 2010,无数据库,使用.net 2.0开发。 2.将GG2014.Server文件夹拷贝到服务上,运行GG2014.Server.exe。 3.修改客户端配置文件GG2014.exe.config中ServerIP配置项的值为服务的IP。 4.运行客户端,注册帐号登录试用。 5.内置测试帐号为 10000,10001,10002,10003,10004;密码都是 1。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值