Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
Hi Zvoni, the information you provided is exactly what I need, thank you very much!
But its drawing speed is really too slow, I need to study how to improve its drawing speed.
Look at Post #7 resp. #9 in that Thread.
The Author claims "super duper high speed"
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
Look at Post #7 resp. #9 in that Thread.
The Author claims "super duper high speed"
Yes, I tested the code in post #7 and post #9. Its speed is improved by sacrificing the resolution of the graphics, that is, the drawn graph is not a smooth concentric circle, but a concentric circle with gaps.
Yes, I'm learning your control, which is very creative and very powerful. Thank you very much, ColinE66.
Now, I'm thinking about how to simplify it:
(1) Remove cwSlider.
(2) Remove Basic Colours, Recent Picks.
(3) Make the layered concentric circles a smooth transition circle (as I showed in post #1)
(4) In addition, I also want to try to put the R, G, B edit boxes into the title bar of the window.
My ultimate goal is to develop a Color-Picker like VSCode's (see the image below).
Last edited by dreammanor; Nov 6th, 2019 at 07:27 AM.
If you are trying to develop one yourself, excellent...but if you want one that has already been created in VB6 (not by me), open (and compile) this one attached. (I use this very, very often, and not only in development of VB6 programs, but others as well. Excellently made!
If you are trying to develop one yourself, excellent...but if you want one that has already been created in VB6 (not by me), open (and compile) this one attached. (I use this very, very often, and not only in development of VB6 programs, but others as well. Excellently made!
Thank you, SamOscarBrown. The control you recommend is good, but its style is classic. I need a clean, flat Color-Picker. I plan to develop one similar to VSCode's based on ColinE66's control.
From my perspective, it seems you need to study a bit about colors and how they work. First, that color wheel you've provided doesn't allow a selection of near anywhere all the possible colors. For instance, how would we select black? Or, for that matter, how would we select any colors that are dark?
The basic problem is that color selection is a three dimensional (or three degrees of freedom) problem (Red, Green, & Blue). And we're always trying to do it in two dimensions (a computer screen). There have been many attempts at solving this problem. Possibly, the simplest is three sliders (black-to-red, black-to-green, & black-to-blue). However, you are correct that people prefer to see something analogous to your color wheel.
The two most widely accepted solutions are referred to as Hue/Saturation/Value (aka, HSV) and Hue/Saturation/Lightness (aka, HSL). The HSV approach truly reduces the problem to two dimensions. And here's a typical 2D HSV selection image:
Now, the HSV approach is pretty nice. In fact, you could use this approach with a reworking of your color wheel, if you expanded it out farther such that the outer edge went all the way to black.
But the HSL approach has become more widely accepted. Basically, it just adds a third selection slider for specifying the lightness factor. And it is precisely this HSL approach that has been adopted by the common dialog of Windows. And, IMHO, why should we re-invent the wheel when it's all done for us in Windows?
Here is a screenshot of the HSL approach provided in Windows (specifically, the right side):
You'll see the hue and saturation selector (the large colorful palette). Basically, horizontal is hue and vertical is saturation. And then, we've got a lightness slider off to the far right. That provides us with our three dimensions (which can be perfectly reworked into RGB if we so desire).
Now, if you'd like to use what's readily available to us in Windows (and follow the standard), here's the code I use to do precisely that (two sections, one for a BAS module, and the other just for some testing in a Form1):
For BAS module:
Code:
Option Explicit
Private Type POINTAPI
x As Long
Y As Long
End Type
Private Type KeyboardInput '
dwType As Long ' Set to INPUT_KEYBOARD.
wVK As Integer ' shift, ctrl, menukey, or the key itself.
wScan As Integer ' Not being used.
dwFlags As Long ' HARDWAREINPUT hi;
dwTime As Long ' Not being used.
dwExtraInfo As Long ' Not being used.
dwPadding As Currency ' Not being used.
End Type
Private Type ChooseColorType
lStructSize As Long
hWndOwner As Long
hInstance As Long
rgbResult As Long
lpCustColors As Long
Flags As Long
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type
Private Enum ChooseColorFlagsEnum
CC_RGBINIT = &H1 ' Make the color specified by rgbResult be the initially selected color.
CC_FULLOPEN = &H2 ' Automatically display the Define Custom Colors half of the dialog box.
CC_PREVENTFULLOPEN = &H4 ' Disable the button that displays the Define Custom Colors half of the dialog box.
CC_SHOWHELP = &H8 ' Display the Help button.
CC_ENABLEHOOK = &H10 ' Use the hook function specified by lpfnHook to process the Choose Color box's messages.
CC_ENABLETEMPLATE = &H20 ' Use the dialog box template identified by hInstance and lpTemplateName.
CC_ENABLETEMPLATEHANDLE = &H40 ' Use the preloaded dialog box template identified by hInstance, ignoring lpTemplateName.
CC_SOLIDCOLOR = &H80 ' Only allow the user to select solid colors. If the user attempts to select a non-solid color, convert it to the closest solid color.
CC_ANYCOLOR = &H100 ' Allow the user to select any color.
End Enum
#If False Then ' Intellisense fix.
Public CC_RGBINIT, CC_FULLOPEN, CC_PREVENTFULLOPEN, CC_SHOWHELP, CC_ENABLEHOOK, CC_ENABLETEMPLATE, CC_ENABLETEMPLATEHANDLE, CC_SOLIDCOLOR, CC_ANYCOLOR
#End If
'
Private Declare Function ChooseColorAPI Lib "comdlg32" Alias "ChooseColorA" (pChoosecolor As ChooseColorType) As Long
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Function ScreenToClient Lib "user32" (ByVal hWnd As Long, lpPoint As POINTAPI) As Long
Private Declare Function ChildWindowFromPointEx Lib "user32" (ByVal hWnd As Long, ByVal xPoint As Long, ByVal yPoint As Long, ByVal uFlags As Long) As Long
Private Declare Function SetFocusTo Lib "user32" Alias "SetFocus" (Optional ByVal hWnd As Long) As Long
Private Declare Function SendInput Lib "user32" (ByVal nInputs As Long, pInputs As Any, ByVal cbSize As Long) As Long
Private Declare Function SendMessageLongW Lib "user32" Alias "SendMessageW" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowTextW Lib "user32" (ByVal hWnd As Long, ByVal lpString As Long, ByVal cch As Long) As Long
'
Private msColorTitle As String
Private pt32 As POINTAPI
Private muEvents(1) As KeyboardInput ' Just used to emulate "Enter" key.
'
Public ColorDialogSuccessful As Boolean
Public ColorDialogColor As Long
'
Public Function ShowColorDialog(hWndOwner As Long, lDefaultColor As Long, Optional NewColor As Long, Optional Title As String = "Select Color", Optional CustomColorsHex As String) As Boolean
' You can optionally use ColorDialogSuccessful & ColorDialogColor or the return of ShowColorDialog and NewColor. They will be the same.
'
' CustomColorHex is a comma separated hex string of 16 custom colors. It's best to just let the user specify these, starting out with all black.
' If this CustomColorHex string doesn't separate into precisely 16 values, it's ignored, resulting with all black custom colors.
' The string is returned, and it's up to you to save it if you wish to save your user-specified custom colors.
' These will be specific to this program, because this is your CustomColorsHex string.
'
Dim uChooseColor As ChooseColorType
Dim CustomColors(15) As Long
Dim sArray() As String
Dim i As Long
'
msColorTitle = Title
'
' Setup custom colors.
sArray = Split(CustomColorsHex, ",")
If UBound(sArray) = 15 Then
For i = 0 To 15
CustomColors(i) = Val("&h" & sArray(i))
Next
End If
'
uChooseColor.hWndOwner = hWndOwner
uChooseColor.lpCustColors = VarPtr(CustomColors(0))
uChooseColor.Flags = CC_ENABLEHOOK Or CC_FULLOPEN Or CC_RGBINIT
uChooseColor.hInstance = App.hInstance
uChooseColor.lStructSize = LenB(uChooseColor)
uChooseColor.lpfnHook = ProcedureAddress(AddressOf ColorHookProc)
uChooseColor.rgbResult = lDefaultColor
'
ColorDialogSuccessful = False
If ChooseColorAPI(uChooseColor) = 0 Then
Exit Function
End If
If uChooseColor.rgbResult > vbWhite Then Exit Function
'
ColorDialogColor = uChooseColor.rgbResult
NewColor = uChooseColor.rgbResult
ColorDialogSuccessful = True
ShowColorDialog = True
'
' Return custom colors.
ReDim sArray(15)
For i = 0 To 15
sArray(i) = Hex$(CustomColors(i))
Next
CustomColorsHex = Join(sArray, ",")
End Function
Private Function ColorHookProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Const WM_SHOWWINDOW As Long = 24&
Const WM_LBUTTONDBLCLK As Long = 515&
Const KEYEVENTF_KEYUP As Long = 2&
Const KEYEVENTF_KEYDOWN As Long = 0&
Const INPUT_KEYBOARD As Long = 1&
'
If uMsg = WM_SHOWWINDOW Then
SetWindowText hWnd, msColorTitle
ColorHookProc = 1&
End If
'
If uMsg = WM_LBUTTONDBLCLK Then
'
' If we're on a hWnd with text, we probably should ignore the double-click.
GetCursorPos pt32
ScreenToClient hWnd, pt32
'
If WindowText(ChildWindowFromPointEx(hWnd, pt32.x, pt32.Y, 0&)) = vbNullString Then
' For some reason, this SetFocus is necessary for the dialog to receive keyboard input under certain circumstances.
SetFocusTo hWnd
' Build EnterKeyDown & EnterKeyDown events.
muEvents(0).wVK = vbKeyReturn: muEvents(0).dwFlags = KEYEVENTF_KEYDOWN: muEvents(0).dwType = INPUT_KEYBOARD
muEvents(1).wVK = vbKeyReturn: muEvents(1).dwFlags = KEYEVENTF_KEYUP: muEvents(1).dwType = INPUT_KEYBOARD
' Put it on buffer.
SendInput 2&, muEvents(0), Len(muEvents(0))
ColorHookProc = 1&
End If
End If
End Function
Private Function ProcedureAddress(AddressOf_TheProc As Long) As Long
ProcedureAddress = AddressOf_TheProc
End Function
Public Sub SetWindowText(hWnd As Long, sText As String)
Const WM_SETTEXT As Long = &HC&
SendMessageLongW hWnd, WM_SETTEXT, 0&, StrPtr(sText)
End Sub
Private Function WindowText(hWndOfInterest As Long) As String
' Form or control.
Dim l As Long
Do
WindowText = Space$(Len(WindowText) + 100&)
l = GetWindowTextW(hWndOfInterest, StrPtr(WindowText), Len(WindowText) + 1&)
If l < Len(WindowText) Then Exit Do
Loop
WindowText = Left$(WindowText, l)
End Function
For Form1 for testing:
Code:
Option Explicit
Private Sub Form_Click()
ShowColorDialog Me.hWnd, &H0, , "Select My Color"
If ColorDialogSuccessful Then
MsgBox "My chosen color is: " & Hex$(ColorDialogColor)
Else
MsgBox "We canceled color selection."
End If
End Sub
Now, if you would still like to develop your color wheel (possibly expanding it to use the HSV approach), best of luck finding some math to convert the X,Y values from clicking it into RGB values. I can post some math that does it for the above rectangle, but I don't have anything for doing it based on a wheel.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Just as a further FYI, here's the kind of color wheel you'd need to fully implement an HSV approach:
Also, it dawns on me that, with a bit of ATan2 work (with the center of the wheel as (0,0)) you could possibly get this done. The length of the click radius (from that (0,0) position) would provide both the Saturation and Value values. I searched for some code that would take the angle of ATan2 and the length of the click radius and convert to RGB, but I didn't find anything. But those are pretty big clues on how to get it done. Anything in the corners (outside of the circle) would need to be interpreted as white. And anything in the center would be black. In fact, I'd turn the center black.
EDIT1: Here's another pretty nice HSV color wheel:
Last edited by Elroy; Nov 6th, 2019 at 10:52 AM.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Also, possibly as a final comment on all of this, one of the critiques of the HSV colorwheel approach, as opposed to the Windows HSL approach is that you can't get a true GRAY with HSV. With HSV, you're forced to select a hue, even if you push it to white or black, so, no gray. With HSL, you can truly push saturation to zero, and then select your lightness level to get any shade of gray you like. In other words, to truly get all the possible colors, you somehow need three separate dimensions.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Also, possibly as a final comment on all of this, one of the critiques of the HSV colorwheel approach, as opposed to the Windows HSL approach is that you can't get a true GRAY with HSV. With HSV, you're forced to select a hue, even if you push it to white or black, so, no gray. With HSL, you can truly push saturation to zero, and then select your lightness level to get any shade of gray you like. In other words, to truly get all the possible colors, you somehow need three separate dimensions.
That's pretty much what my colour wheel does in the post above: Hue around the circumference, Luminance across the radius, and a saturation slider.
If you don't know where you're going, any road will take you there...
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Hello, I am going to contribute my grain of sand, surely the fans will say that it is crap, it is, but for some cases in particular it is a quick exit. with so many cute palettes on the internet because I don't use an image.
keep in mind that it is a very limited method since you cannot mark the color automatically (in reality it could be but it would be your job) the same as the brightness could also be
All very good and cool (Elroy's suggestion on not reinventing the wheel is spot on---use Windows like he did).
BUT, just to point out ONE thing in that program I posted (again, not mine), it allows one to find ANY COLOR on ANY part of your screen(s), IOW, let's say I see a color I like on some website or some application I am running...opening ColorPicker (the program I posted), you click a button, then click on the object having the color you desire, and it gives you HEX, "VB" and RGB....REALLY a great app.
But, if you don't want to use it ALONG WITH Elroy's suggestion (or maybe one of the many others offered), then so be it...but it IS cool!
Hi @Elroy, the information and code you provided is very useful, thank you very much. My idea is this, splitting the Color-Wheel that you showed at the end of post #13 into two parts: an outer bright ring and an inner shadow circle. Turn the outer bright ring into the Color-Wheel that I showed in post #1; turn the inner shadow circle into a vertical brightness slider or color slider (see the image below). Also, I'm testing and rewriting your code. After the rewrite is complete, I'll upload the code and continue the discussion. Thanks again.
Might be worth checking out Tanner Helland's colour wheel implementation in PhotoDemon.
It has 2 sections - an outer wheel where you select the colour, then an inner box where you select the shade. Mind the license though!
Hi jpbro, thank you for your suggestion and reminder. I noticed the copyright statement of PhotoDemon. I have never used Tanner's code, but I admire Tanner's contribution to the VB open source community and hope that the excellent PhotoDemon will have more and more users.
In addition, I found a similar control to PhotoDemon's Color-Wheel in PsCode, but this control is not as refined and professional as Tanner's. I guess Tanner's Color-Wheel is drawn using GDIPlus, and the one in PsCode is drawn with GDI, so its edges are jagged. I'll try to draw a Color-Wheel like Tanner with Cairo.
All very good and cool (Elroy's suggestion on not reinventing the wheel is spot on---use Windows like he did).
BUT, just to point out ONE thing in that program I posted (again, not mine), it allows one to find ANY COLOR on ANY part of your screen(s), IOW, let's say I see a color I like on some website or some application I am running...opening ColorPicker (the program I posted), you click a button, then click on the object having the color you desire, and it gives you HEX, "VB" and RGB....REALLY a great app.
But, if you don't want to use it ALONG WITH Elroy's suggestion (or maybe one of the many others offered), then so be it...but it IS cool!
Sam
Thank you, SamOscarBrown.
Originally Posted by LeandroA
Hello, I am going to contribute my grain of sand, surely the fans will say that it is crap, it is, but for some cases in particular it is a quick exit. with so many cute palettes on the internet because I don't use an image.
keep in mind that it is a very limited method since you cannot mark the color automatically (in reality it could be but it would be your job) the same as the brightness could also be
Hi LeandroA, I checked your code, it's very good, thank you!
Originally Posted by Eduardo-
I played a bit and also made a color wheel.
PS: updated, new version.
Hi Eduardo-, I tested your code and it worked well, thank you. Elroy's ColorWheel is smooth, and your ColorWheel has discontinuous dark lines, and I wonder if there is any way to eliminate it.
Edit:
Elroy's Color-Wheel is a picture, not drawn dynamically.
Last edited by dreammanor; Nov 7th, 2019 at 09:06 AM.
Again, how do we select Black (or even Maroon or Navy Blue) from that color wheel?
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Ahh, yes. That's taking more of an HSL approach. Your black-to-white slide provides the Lightness component. Also, it recognizes that, even as a wheel, in that wheel-palette, we've still only got two dimensions, and are lacking a third (provided by your slider).
This is essentially the same thing as what's provided by Windows API, just in a wheel form. But, if that's what you want, I think it's great.
Also, just for grins, I might adapt my code to your situation. Also, it's my understanding that it's the standard for any color wheel to have Yellow as straight-up and Blue as straight-down, so that's the way I'll do it.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Ahh, yes. That's taking more of an HSL approach. Your black-to-white slide provides the Lightness component. Also, it recognizes that, even as a wheel, in that wheel-palette, we've still only got two dimensions, and are lacking a third (provided by your slider).
This is essentially the same thing as what's provided by Windows API, just in a wheel form. But, if that's what you want, I think it's great.
Also, just for grins, I might adapt my code to your situation. Also, it's my understanding that it's the standard for any color wheel to have Yellow as straight-up and Blue as straight-down, so that's the way I'll do it.
Hi Elroy, I want to re-develop a Color-Wheel because the commonly used Windows color picker is too complicated (three colors change at the same time). IMO, Color-Wheel + Slider can make things a bit simpler.
In addition, the bright Color-Wheel with only two dimensions is very beautiful, isn't it?
Yes, that was a side effect of trying to make it to draw faster.
Here is a new version that is smooter, but takes a little longer to draw and the size cannot be as big as the other.
Hi Eduardo, I tested your code, which is great, it's very close to a smooth Color-Wheel. I wonder if there is an API faster than UserControl.PSet. Also, if using a double buffer to draw color points, would it be faster? Maybe The trick and LaVolpe could offer some advice.
Well, personally, I'll probably stick with the Windows common dialog API for my published software. However, dabbling in this is a bit fun. Yeah, I like the aesthetics of the wheel, but we do need that third dimension to be complete (i.e., the slider).
Also, just looking around for a good wheel on which to base things, it amazes me how many different approaches there are, and takes me back to my physiology (and retinal anatomy) training. From a physiology perspective, we have three types of "daytime" photo-receptors (called cones). One type sees Red (564nm light wavelengths), one type sees Green (534nm wavelengths), and one type sees Blue (420nm wavelengths). Notice that they're not evenly space, and that Red and Green are much closer than either is to Blue. It's our brain processing that more-or-less equalizes these.
However, from a pure physics perspective, this provides us with two alternatives to developing a color wheel: 1) based on evenly spaced wavelengths, or 2) based on evenly spaced Red/Green/Blue, with some kind of smooth interpolation between those. When looking around, you can find both approaches.
In addition, you can find the old Red-Yellow-Blue type color wheels. This Red-Yellow-Blue is just a hangover from many years ago before we fully understood photo-receptors. Basically, it was just an attempt by the artists community to make sense of colors. They got it close to correct, but missed slightly with the Yellow. But you still see these ideas carried forward in contemporary artist communities.
So, there are choices to be made.
Being a computer geek, and knowing that ALL computer screens (well, other than old monochrome ones) have sub-pixel-triads within each pixel, with these triads having a Red, Green, & Blue sub-pixel that are "tuned" to our photo-receptors, I tend to start from there. Also, when building an RGB color, it makes the math much easier. So, stated differently, I tend to just completely ignore the fact that Red, Green, & Blue aren't truly equal-distant apart with respect to light wavelength frequency.
Fun fact: If you've got a good magnifying glass, it's fun to hold it up to a computer monitor and look at the RGB sub-pixels. I've got a little hand-held bug examiner toy I use. It's 30x power. I tried to hold my phone up to it and take a picture, but it wouldn't work. However, I did find this, which is pretty close to what I saw:
And, by mixing those RGB colors, we can effectively "trick" our brains into thinking they're seen any/all the colors we can see. In nature, colors aren't limited to RGB. However, because our photoreceptors ARE limited to RGB, this works.
So, taking a color-additive approach, everything ultimately comes back to RGB, with everything else (HSL, HSV, etc) being an attempt to represent this RGB in a more colorful fashion.
So, back to the task at hand. It's my preference to make an equilateral triangle out of RGB, another equilateral triangle turned 60° out of Yellow, Cyan, & Magenta (where Yellow=Red+Green, Cyan=Green+Blue, & Magenta=Blue+Red), with smooth interpolations for everything in-between. Taking an HSV approach, we'd tend to put WHITE in the middle (based on the Value). Taking an HSL approach, we'd tend to put GRAY in the middle (based on the Lightness). I think I sort of like the WHITE in the middle though.
So, if the HSV approach is taken, it'd also be nice if the whole color wheel brightened and dimmed when the Value slider was moved. That might take some GdiPlus work to get going, but that might be fun too. First, I've got to find a color-wheel I really like. That one you posted in the OP is pretty nice (if rotated so that Yellow is straight up).
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Hi Eduardo, I tested your code, which is great, it's very close to a smooth Color-Wheel. I wonder if there is an API faster than UserControl.PSet.
I see that I forgot and left two methods of drawing the dots: with the API LineTo and with UserControl.PSet.
But now with the smoother color wheel if I remove any of the two, white dots appear.
I leave to you to experiment if you want.
Originally Posted by dreammanor
Also, if using a double buffer to draw color points, would it be faster?
What do you mean with double buffer?
For example to have a 24 bits bitmap in memory, and use GetDIBits/SetDIBits and draw in the byte arrays and then to paint the image?
May be faster, but it would need to be tested.
Originally Posted by dreammanor
Maybe The trick and LaVolpe could offer some advice.
Yes, sure.
Anyway, the best approach may be to use an already drawn image (Elroy's approach). The only issue is that you'll have to ship the 1MB image.
Well, personally, I'll probably stick with the Windows common dialog API for my published software. However, dabbling in this is a bit fun. Yeah, I like the aesthetics of the wheel, but we do need that third dimension to be complete (i.e., the slider).
Also, just looking around for a good wheel on which to base things, it amazes me how many different approaches there are, and takes me back to my physiology (and retinal anatomy) training. From a physiology perspective, we have three types of "daytime" photo-receptors (called cones). One type sees Red (564nm light wavelengths), one type sees Green (534nm wavelengths), and one type sees Blue (420nm wavelengths). Notice that they're not evenly space, and that Red and Green are much closer than either is to Blue. It's our brain processing that more-or-less equalizes these.
However, from a pure physics perspective, this provides us with two alternatives to developing a color wheel: 1) based on evenly spaced wavelengths, or 2) based on evenly spaced Red/Green/Blue, with some kind of smooth interpolation between those. When looking around, you can find both approaches.
In addition, you can find the old Red-Yellow-Blue type color wheels. This Red-Yellow-Blue is just a hangover from many years ago before we fully understood photo-receptors. Basically, it was just an attempt by the artists community to make sense of colors. They got it close to correct, but missed slightly with the Yellow. But you still see these ideas carried forward in contemporary artist communities.
So, there are choices to be made.
Being a computer geek, and knowing that ALL computer screens (well, other than old monochrome ones) have sub-pixel-triads within each pixel, with these triads having a Red, Green, & Blue sub-pixel that are "tuned" to our photo-receptors, I tend to start from there. Also, when building an RGB color, it makes the math much easier. So, stated differently, I tend to just completely ignore the fact that Red, Green, & Blue aren't truly equal-distant apart with respect to light wavelength frequency.
Fun fact: If you've got a good magnifying glass, it's fun to hold it up to a computer monitor and look at the RGB sub-pixels. I've got a little hand-held bug examiner toy I use. It's 30x power. I tried to hold my phone up to it and take a picture, but it wouldn't work. However, I did find this, which is pretty close to what I saw:
And, by mixing those RGB colors, we can effectively "trick" our brains into thinking they're seen any/all the colors we can see. In nature, colors aren't limited to RGB. However, because our photoreceptors ARE limited to RGB, this works.
So, taking a color-additive approach, everything ultimately comes back to RGB, with everything else (HSL, HSV, etc) being an attempt to represent this RGB in a more colorful fashion.
So, back to the task at hand. It's my preference to make an equilateral triangle out of RGB, another equilateral triangle turned 60° out of Yellow, Cyan, & Magenta (where Yellow=Red+Green, Cyan=Green+Blue, & Magenta=Blue+Red), with smooth interpolations for everything in-between. Taking an HSV approach, we'd tend to put WHITE in the middle (based on the Value). Taking an HSL approach, we'd tend to put GRAY in the middle (based on the Lightness). I think I sort of like the WHITE in the middle though.
So, if the HSV approach is taken, it'd also be nice if the whole color wheel brightened and dimmed when the Value slider was moved. That might take some GdiPlus work to get going, but that might be fun too. First, I've got to find a color-wheel I really like. That one you posted in the OP is pretty nice (if rotated so that Yellow is straight up).
Hi Elroy, your knowledge is very profound, I admire very much. I want to make a Color-Picker that is different from VSCode's (see the image below), so I want to use Color-Wheel instead of VSCode's gradient rectangle. I don't know if I chose a wrong solution.
What do you mean with double buffer?
For example to have a 24 bits bitmap in memory, and use GetDIBits/SetDIBits and draw in the byte arrays and then to paint the image?
May be faster, but it would need to be tested.
Hi Eduardo, I'm sorry that I have used a vague and inaccurate word. What I mean by "double buffering" is to first draw the image in a memory DC and then copy it into the PictureBox.
Ok, here's my first pass at a true HSV scheme with a color-wheel.
And a little demo project is attached.
I still think it would be nice if the Hue-Saturation picture was change according to the light-dark value. And also, we could change the light-dark (value) slider to reflect the chosen hue and saturation. But that would take a bit more work, and I've got other things going on here, so we'll see.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Hi Eduardo, I'm sorry that I have used a vague and inaccurate word. What I mean by "double buffering" is to first draw the image in a memory DC and then copy it into the PictureBox.
As a user I make an awful lot of use of the Common Dialog's "custom color" pots and I'd miss them.
Well, there's nothing to stop Dreammanor from doing that with his wheel. With the Common Dialog, you have to keep track of your own "pots" anyway, so it really wouldn't be much different.
I agree though that we're reinventing the wheel (pun intended I suppose). It might be nice though to have an option where you could select colors right on your form (rather than have a common dialog pop up). However, if I were actually going to implement something like that, I'd probably copy the Common Dialog (HSL with square palette) approach. But splashing around with this stuff is somewhat fun.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.