05-10-12, 06:47 PM
لكي نبني كونترول يأخذ أي صورة ويقوم بتحويلها الي ColorPicker نحتاج إلي أن نستخدم الوراثة من كونترول عادي Control Class ثم نضيف بعض السمات الجديدة الي الكونترول وهي كالأتي
1- متغير يعبر عن أي صورة ....... ولذلك سنحتاج أيضا الي Property لهذا الغرض
2- متغير عبارة عن نقطة Point يعبر عن مكان الماوس علي الصورة....
3- نحتاج الي إضافة حدث Event تأكد منه أن مكان الماوس علي الصورة قد تغير وبالتالي نطلق هذا الحدث ومن ثم نسترجع لون ما من الصورة بناء علي ذلك
4- نحتاج الي استرجاع اللون من الصورة لذلك سنحتاج الي Property لهذا الغرض
لنبدأ بناء الكونترول .........
الخطوات التالية توضح كيفية بناء الكونترول بالتفصيل
1- من قائمة File علك باختيار New Project "مشروع جديد" ثم من نافذة New Project عليك أن تختار نوع هذا المشروع وبما أننا نبني كونترول جديد ليكن مشروعنا من النوع Class Library وأعطي لمشروعك أي إسم تراه مناسبا
2- ثم من قائمة Project نختار Add Reference..... وهنا ستظهر لك نافذة Add Reference ومنها عليك إضافة فضاء الأسماء التالية
System.Windows.Forms
System.Drawing
3- قم بتغيير إسم الكلاس الموجود في المشروع من Class1 الي ImageColorPicker أو يمكنك استخدام أي مسمي تراه مناسبا
4- استخدم جملة Imports ثم أضف فضاء الأسماء التالية الي الكلاس
System.Windows.Forms
System.Drawing
System.Drawing.Drawing2D
System.ComponentModel
5- استخدم جملة Inherit للتوريث من Control Class
لو تم تنفيذ الخطوات أعلاه بشكل دقيق ستحصل عل الشكل التالي من الكود
6- أضف المتغيرات التالية إلي الكلاس
- المتغير الأول عبارة عن Integer وهو يعبر عن البعد بين مكان رسم الصورة علي الكونترول و Control ClientRectangle أو بمعني أدق يعبر عن Padding حول الصورة المرسومة عل الكونترول
- المتغير الثاني عبارة عن Color وهو اللون الذي نحتاج أن نسترجعه من الكونترول
- المتغير الثالث يعبر عن نقطة Point وهو يمثل النقطة التي تحدد مكان اللون علي الصورة وذلك عندما يتحرك الماوس علي الصورة المرسومة علي الكونترول
- المتغير الرابع وهو عبارة عن Bitmap وهو يمثل الصورة التي سيقوم مستخدم الكونترول بتحديدها لكي يتم رسمها علي الكونترول وهي تتغير تبعا لرغبة المستخدم
- المتغير الخامس والأخير عبارة عن Bitmap أيضا وهو يمثل الصورة الحقيقية التي يتم رسمها علي الكونترول وهي لا تظهر للمستخدم
7- أضف Constructor التالي الي الكونترول والمقصد هنا هو إضافة Sub New
والهدف الأوحد من الأكواد هو تقليل حجم Flicker أثناء عملية الرسم علي الكونترول
8- قبل أن نكتب أي أكواد أخري نحتاج الي كتابة الروتين الأتي والهدف منه هو التاكد أن أي نقطة سنحددها لاحقا يجب أن تكون داخل حدود الصورة المرسومة علي الكونترول والكود التالي يوضح شكل هذا الروتين
9- لنكتب رويتنا بسيطا أخر لرسم الصورة وستلاحظون أننا نأخذ الصورة التي يختارها مستخدم الكونترول ثم نعيد رسمها مرة أخري من خلال المتغير internalImage
10- لنكتب دالة بسيطة نتأكد بها من أن النقطة التي يتم استرجاعها عبارة عن لون ونربطها بجملة GetPixel ومن ثم نحدد النقطة المراد إسترجاعها
10- لنضيف الحدث SelectedColorChanged الي الكونترول
11- لنضيف Properties التالية الي الكونترول وأرجو أن تلاحظوا كيف يتم استرجاع اللون بناء علي المتغير selectedPoint
12- أخر شئ نقوم بعمل Overrides لبعض الأحداث الموجودة بالكونترول لكي نرسم الصورة وأيضا لكي نربط المتغير selectedPoint مع حركة الماوس
في المشاركة التالية سوف أضع نسخة من الكود الخاص بالكلاس كاملا وكيفية استخدام هذا الكونترول
تقبلوا تحياتي
أخوكم عمر
1- متغير يعبر عن أي صورة ....... ولذلك سنحتاج أيضا الي Property لهذا الغرض
2- متغير عبارة عن نقطة Point يعبر عن مكان الماوس علي الصورة....
3- نحتاج الي إضافة حدث Event تأكد منه أن مكان الماوس علي الصورة قد تغير وبالتالي نطلق هذا الحدث ومن ثم نسترجع لون ما من الصورة بناء علي ذلك
4- نحتاج الي استرجاع اللون من الصورة لذلك سنحتاج الي Property لهذا الغرض
لنبدأ بناء الكونترول .........
الخطوات التالية توضح كيفية بناء الكونترول بالتفصيل
1- من قائمة File علك باختيار New Project "مشروع جديد" ثم من نافذة New Project عليك أن تختار نوع هذا المشروع وبما أننا نبني كونترول جديد ليكن مشروعنا من النوع Class Library وأعطي لمشروعك أي إسم تراه مناسبا
2- ثم من قائمة Project نختار Add Reference..... وهنا ستظهر لك نافذة Add Reference ومنها عليك إضافة فضاء الأسماء التالية
System.Windows.Forms
System.Drawing
3- قم بتغيير إسم الكلاس الموجود في المشروع من Class1 الي ImageColorPicker أو يمكنك استخدام أي مسمي تراه مناسبا
4- استخدم جملة Imports ثم أضف فضاء الأسماء التالية الي الكلاس
System.Windows.Forms
System.Drawing
System.Drawing.Drawing2D
System.ComponentModel
5- استخدم جملة Inherit للتوريث من Control Class
لو تم تنفيذ الخطوات أعلاه بشكل دقيق ستحصل عل الشكل التالي من الكود
كود :
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.ComponentModel
Public Class ImageColorPicker
Inherits Control
End Class- المتغير الأول عبارة عن Integer وهو يعبر عن البعد بين مكان رسم الصورة علي الكونترول و Control ClientRectangle أو بمعني أدق يعبر عن Padding حول الصورة المرسومة عل الكونترول
- المتغير الثاني عبارة عن Color وهو اللون الذي نحتاج أن نسترجعه من الكونترول
- المتغير الثالث يعبر عن نقطة Point وهو يمثل النقطة التي تحدد مكان اللون علي الصورة وذلك عندما يتحرك الماوس علي الصورة المرسومة علي الكونترول
- المتغير الرابع وهو عبارة عن Bitmap وهو يمثل الصورة التي سيقوم مستخدم الكونترول بتحديدها لكي يتم رسمها علي الكونترول وهي تتغير تبعا لرغبة المستخدم
- المتغير الخامس والأخير عبارة عن Bitmap أيضا وهو يمثل الصورة الحقيقية التي يتم رسمها علي الكونترول وهي لا تظهر للمستخدم
كود :
#Region " Fields "
Private imageBorders As Integer = 5
Private colorSelected As Color = Color.Empty
Private selectedPoint As Point = New Point(-1, -1)
Private pickerImage As Bitmap = Nothing
Private internalImage As Bitmap = Nothing
#End Regionوالهدف الأوحد من الأكواد هو تقليل حجم Flicker أثناء عملية الرسم علي الكونترول
كود :
#Region " Constructor "
Public Sub New()
SetStyle(ControlStyles.SupportsTransparentBackColor, True)
SetStyle(ControlStyles.Opaque, False)
SetStyle(ControlStyles.DoubleBuffer, True)
SetStyle(ControlStyles.AllPaintingInWmPaint, True)
SetStyle(ControlStyles.UserPaint, True)
UpdateStyles()
End Sub
#End Regionكود :
Private Sub CheckColorPoint(ByRef pt As Point)
If (pt.X - Me.imageBorders) < 0 Then
pt.X = Me.imageBorders
End If
If pt.X > ((MyBase.Width - Me.imageBorders) - 1) Then
pt.X = (MyBase.Width - Me.imageBorders) - 1
End If
If (pt.Y - Me.imageBorders) < 0 Then
pt.Y = Me.imageBorders
End If
If pt.Y > ((MyBase.Height - Me.imageBorders) - 1) Then
pt.Y = (MyBase.Height - Me.imageBorders) - 1
End If
End Subكود :
Private Sub DrawPickerImage()
If MyBase.Width > 0 AndAlso Me.pickerImage IsNot Nothing Then
Me.internalImage = New Bitmap(MyBase.Width - (Me.imageBorders * 2), MyBase.Height - (Me.imageBorders * 2))
Dim g As Graphics = Graphics.FromImage(Me.internalImage)
Dim mode As SmoothingMode = g.SmoothingMode
g.SmoothingMode = SmoothingMode.AntiAlias
Dim rect As New Rectangle(0, 0, Me.internalImage.Width, Me.internalImage.Height)
g.DrawImage(pickerImage, rect)
g.SmoothingMode = mode
g.Dispose()
End If
End Sub10- لنكتب دالة بسيطة نتأكد بها من أن النقطة التي يتم استرجاعها عبارة عن لون ونربطها بجملة GetPixel ومن ثم نحدد النقطة المراد إسترجاعها
كود :
Private Function IsColorFromPoint(ByVal pt As Point) As Boolean
Me.CheckColorPoint(pt)
If Me.pickerImage IsNot Nothing Then
If (((pt.X - Me.imageBorders) >= 0) AndAlso ((pt.X - Me.imageBorders) < Me.internalImage.Width)) AndAlso (((pt.Y - Me.imageBorders) >= 0) AndAlso ((pt.Y - Me.imageBorders) < Me.internalImage.Height)) Then
Dim pixelColor As Color = Me.internalImage.GetPixel(pt.X - Me.imageBorders, pt.Y - Me.imageBorders)
If pixelColor.A > 0 Then
Me.colorSelected = pixelColor
Me.selectedPoint.X = pt.X - Me.imageBorders
Me.selectedPoint.Y = pt.Y - Me.imageBorders
Return True
End If
End If
End If
Return False
End Functionكود :
#Region " Events "
Public Custom Event SelectedColorChanged As EventHandler
AddHandler(ByVal value As EventHandler)
Me.Events.AddHandler("SelectedColorChangedEvent", value)
End AddHandler
RemoveHandler(ByVal value As EventHandler)
Me.Events.RemoveHandler("SelectedColorChangedEvent", value)
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
CType(Me.Events("SelectedColorChangedEvent"), EventHandler).Invoke(sender, e)
End RaiseEvent
End Event
#End Regionكود :
#Region " Properties "
Public Property SelectedColor() As Color
Get
Return Me.colorSelected
End Get
Set(ByVal value As Color)
Me.colorSelected = value
Dim w As Integer = MyBase.Width - (2 * Me.imageBorders)
Dim h As Integer = MyBase.Height - (2 * Me.imageBorders)
Me.selectedPoint.X = ((255 - Me.SelectedColor.GetBrightness()) * w) / 255
Me.selectedPoint.Y = ((255 - Me.SelectedColor.GetSaturation) * h) / 255
Me.DrawPickerImage()
MyBase.Invalidate()
End Set
End Property
Public Property Image As Bitmap
Get
Return Me.pickerImage
End Get
Set(ByVal value As Bitmap)
Me.pickerImage = value
Me.DrawPickerImage()
Me.Invalidate()
End Set
End Property
Protected Overrides ReadOnly Property DefaultSize As System.Drawing.Size
Get
Return New Size(100, 100)
End Get
End Property
#End Regionكود :
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseDown(e)
If Me.IsColorFromPoint(e.Location) Then
If Not Me.Focused Then
MyBase.Focus()
End If
MyBase.Invalidate()
Me.onSelectedcolorchanged(New EventArgs())
End If
End Sub
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseMove(e)
If (e.Button = MouseButtons.Left) AndAlso Me.IsColorFromPoint(e.Location) Then
MyBase.Invalidate()
Me.onSelectedcolorchanged(New EventArgs())
End If
End Sub
Protected Overrides Sub OnEnter(ByVal e As System.EventArgs)
MyBase.OnEnter(e)
MyBase.Invalidate()
End Sub
Protected Overrides Sub OnLeave(ByVal e As System.EventArgs)
MyBase.OnLeave(e)
MyBase.Invalidate()
End Sub
Protected Overrides Sub OnSizeChanged(ByVal e As System.EventArgs)
Me.DrawPickerImage()
MyBase.OnSizeChanged(e)
End Sub
Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
Me.DrawPickerImage()
MyBase.OnResize(e)
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
Dim mode As SmoothingMode = e.Graphics.SmoothingMode
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
If Me.internalImage IsNot Nothing Then
Using lgb As New LinearGradientBrush(Me.ClientRectangle, Color.Black, Color.FromArgb(200, Color.Black), 90, False)
e.Graphics.FillRectangle(lgb, Me.ClientRectangle)
End Using
e.Graphics.DrawImage(Me.internalImage, Me.imageBorders, Me.imageBorders)
End If
If Me.selectedPoint.X > -1 Then
Dim r As New Rectangle((Me.imageBorders + Me.selectedPoint.X) - 5, (Me.imageBorders + Me.selectedPoint.Y) - 5, 10, 10)
Using sb As Brush = New SolidBrush(Me.colorSelected)
e.Graphics.FillEllipse(sb, r)
End Using
e.Graphics.DrawEllipse(Pens.White, r)
r.Inflate(1, 1)
e.Graphics.DrawEllipse(Pens.Black, r)
End If
e.Graphics.SmoothingMode = mode
End Sub
Protected Sub onSelectedcolorchanged(ByVal e As EventArgs)
Dim handler As EventHandler = CType(Me.Events("SelectedColorChangedEvent"), EventHandler)
If handler IsNot Nothing Then
handler.Invoke(Me, e)
End If
End Subفي المشاركة التالية سوف أضع نسخة من الكود الخاص بالكلاس كاملا وكيفية استخدام هذا الكونترول
تقبلوا تحياتي
أخوكم عمر
