VB中HSL怎么转换为RGB?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VB中HSL怎么转换为RGB?相关的知识,希望对你有一定的参考价值。

如题,请详细的告诉我(最好是告诉我源代码,H=1,S=2,L=3),只要HSL→RGB

这里有代码 HSL和RGB互转的 (注:HSB就是HSL,B和L都有亮度的意思)

Public Type HSB
    Hue As Integer           
    Saturation As Integer    
    Brightness As Integer    
End Type
Public Type RGB
    Red As Integer           
    Green As Integer        
    Bue As Integer
End Type
' 转换RGB到HSB
Public Function RGB2HSB(ByVal R As Integer, ByVal G As Integer, ByVal B As Integer) As HSB
    Dim nH As Single, nS As Single, nV As Single
    Dim nR As Single, nG As Single, nB As Single
    Dim ndelR As Single, ndelG As Single, ndelB As Single
    Dim nmax As Single, nmin As Single, ndelMax As Single

    nR = R / 255
    nG = G / 255
    nB = B / 255
    nmax = Max(Max(nR, nG), nB)
    nmin = Min(Min(nR, nG), nB)
    ndelMax = nmax - nmin
    nV = nmax
    If (ndelMax = 0) Then
        nH = 0
        nS = 0

    Else
        nS = ndelMax / nmax
        ndelR = (((nmax - nR) / 6) + (ndelMax / 2)) / ndelMax
        ndelG = (((nmax - nG) / 6) + (ndelMax / 2)) / ndelMax
        ndelB = (((nmax - nB) / 6) + (ndelMax / 2)) / ndelMax
        If (nR = nmax) Then
            nH = ndelB - ndelG
        ElseIf (nG = nmax) Then
            nH = (1 / 3) + ndelR - ndelB
        ElseIf (nB = nmax) Then
            nH = (2 / 3) + ndelG - ndelR
        End If
        If (nH < 0) Then nH = nH + 1
        If (nH > 1) Then nH = nH - 1

    End If
    RGB2HSB.Hue = nH * 360
    RGB2HSB.Saturation = nS * 100
    RGB2HSB.Brightness = nV * 100
    
End Function
' 转换HSB到RGB
Public Function HSB2RGB(ByVal H As Integer, ByVal S As Integer, ByVal B As Integer) As RGB
    Dim nH As Single, nS As Single, nV As Single
    Dim nR As Single, nG As Single, nB As Single
    Dim hi As Single, f As Single, p As Single, q As Single, t As Single
    
    nH = H / 360
    nS = S / 100
    nV = B / 100
    If (S = 0) Then
        nR = nV * 255
        nG = nV * 255
        nB = nV * 255
    Else
        hi = nH * 6
        If (hi = 6) Then hi = 0
        f = Int(hi)
        p = nV * (1 - nS)
        q = nV * (1 - nS * (hi - f))
        t = nV * (1 - nS * (1 - (hi - f)))
        If (f = 0) Then
            nR = nV
            nG = t
            nB = p
        ElseIf (f = 1) Then
            nR = q
            nG = nV
            nB = p
        ElseIf (f = 2) Then
            nR = p
            nG = nV
            nB = t
        ElseIf (f = 3) Then
            nR = p
            nG = q
            nB = nV
        ElseIf (f = 4) Then
            nR = t
            nG = p
            nB = nV
        Else
            nR = nV
            nG = p
            nB = q
        End If
    End If
    HSB2RGB.Red = nR * 255
    HSB2RGB.Green = nG * 255
    HSB2RGB.Bue = nB * 255
    
End Function

把H,S,L当成参数调用,返回值就是一个类型为“RGB”的用户定义类型

示例:

Dim aa As RGB
aa=HSB2RGB(1, 2, 3)
Print "R:" & aa.Red & " G:" & aa.Green & " B:" & aa.Bue

回答得很晚,不知道能否帮到题主,请您设为最佳答案把 谢谢!

参考技术A 网上找去啊。N多现成的算法,N多现成的代码啊。这个东西。
百度百科里面就有,怎么不看呢。
HSL→RGB的算法描述。
  步骤1:If S=0,表示灰色,定义R,G和B都为L.
  步骤2:否则,测试L:
  If L<0.5,temp2=L*(1.0+S)
  If L>=0.5,temp2=L+S-L*S
  步骤3:temp1=2.0*-temp2
  步骤4:把H转换到0~1。
  步骤5:对于R,G,B,计算另外的临时值temp3。方法如下:
  for R, temp3=H+1.0/3.0
  for G, temp3=H
  for B, temp3=H-1.0/3.0
  if temp3<0, temp3=temp3+1.0
  if temp3>1, temp3=temp3-1.0
  步骤6:对于R,G,B做如下测试:
  If 6.0*temp3<1,color=temp1+(temp2-temp1)*6.0*temp3
  Else if 2.0*temp3<1,color=temp2
  Else if 3.0*temp3<2,
  color=temp1+(temp2-temp1)*((2.0/3.0)-temp3)*6.0
  Else color=temp1追问

请列出具体怎么弄,源代码

参考技术B 建议你用Timer控件来控制,这个快慢也好掌握,不过也可以把你的代码发来看看,好给你解决追问

我是问转换公式

参考技术C RGB转HSB有公式 是啥?反过来算也不麻烦追问

怎么算,不会写代码

参考技术D 只要找到对应的算法就行了追问

就是不知道如何通过色调、饱和度、亮度计算RGB

JavaScript HSL拾色器

HSL 和 HSV 在数学上定义为在 RGB 空间中的颜色的 R, G 和 B 的坐标的变换。

从 RGB 到 HSL 或 HSV 的转换

设 (r, g, b) 分别是一个颜色的红、绿和蓝坐标,它们的值是在 0 到 1 之间的实数。设 max 等价于 r, g 和 b 中的最大者。设 min 等于这些值中的最小者。要找到在 HSL 空间中的 (h, s, l) 值,这里的 h ∈ [0, 360)是角度的色相角,而 s, l ∈ [0,1] 是饱和度和亮度,计算为:

h 的值通常规范化到位于 0 到 360°之间。而 h = 0 用于 max = min 的(就是灰色)时候而不是留下 h 未定义。
HSL 和 HSV 有同样的色相定义,但是其他分量不同。HSV 颜色的 s 和 v 的值定义如下:

从 HSL 到 RGB 的转换

给定 HSL 空间中的 (h, s, l) 值定义的一个颜色,带有 h 在指示色相角度的值域 [0, 360)中,分别表示饱和度和亮度的s 和 l 在值域 [0, 1] 中,相应在 RGB 空间中的 (r, g, b) 三原色,带有分别对应于红色、绿色和蓝色的 r, g 和 b 也在值域 [0, 1] 中,它们可计算为:
首先,如果 s = 0,则结果的颜色是非彩色的、或灰色的。在这个特殊情况,r, g 和 b 都等于 l。注意 h 的值在这种情况下是未定义的。
当 s ≠ 0 的时候,可以使用下列过程:

对于每个颜色向量 Color = (ColorR, ColorG, ColorB) = (r, g, b),

从 HSV 到 RGB 的转换

类似的,给定在 HSV 中 (h, s, v) 值定义的一个颜色,带有如上的 h,和分别表示饱和度和明度的 s 和 v 变化于 0 到 1 之间,在 RGB 空间中对应的 (r, g, b) 三原色可以计算为:

对于每个颜色向量 (r, g, b),

<html>
    <style>
        .childDiv 
            display:inline-block;   
            vertical-align:middle;
            margin-left: 30px;
            margin-top: 10px;
            margin-bottom: 10px;
        
        #colorPickDiv 
            background-color: WhiteSmoke;
            border: 1px solid LightGrey;
            padding-top: 20px;
            padding-bottom: 20px;
            padding-right: 30px;
        
        #hueTipDiv 
            margin: 0 0 10px 70px;
        
        #luminanceTipDiv 
            margin-top: 20px
        
        #colorDiv 
            width: 100px;
            height: 100px;
            background-color: black;
        
        #valueDiv 
            box-shadow: 0px -5px 10px LightGrey;
            background-color: WhiteSmoke;
            border: 1px solid LightGrey;
            border-top-width: 0;
            padding-right: 10px;
            padding-bottom: 10px;
        
    </style>
    <body>
        <div>
            <div id="colorPickDiv">
                <div class="childDiv">
                    <div id="hueTipDiv">Hue:0</div>
                    <canvas id="canvas" width="200" height="200">Your browser does not support canvas</canvas>
                </div>
                <div class="childDiv">
                    <div id="saturationTipDiv" class="divMarginBottom">Saturation:0%</div>
                    <input id="saturationRange" onChange="onHSLRangeChange()" type="range" min="0" max="100" step="1" value="100"/>
                    <div id="luminanceTipDiv" class="divMarginBottom">Luminance:0%</div>
                    <input id="luminanceRange" onChange="onHSLRangeChange()" type="range" min="0" max="100" step="1" value="50"/>
                </div>
                <div id="colorDiv" class="childDiv"></div>
            </div>
            <div id="valueDiv">
                <div class="childDiv">
                    <div id="hexadecimalTipDiv" class="divMarginBottom">Hexadecimal:</div>
                    <input id="hexadecimalValueDiv" type="text" disabled="disabled"/>
                </div>
                <div class="childDiv">
                    <div id="rgbTipDiv" class="divMarginBottom">RGB:</div>
                    <input id="rgbValueDiv" type="text" readonly="readonly"/>
                </div>
                <div class="childDiv">
                    <div id="hslTipDiv" class="divMarginBottom">HSL:</div>
                    <input id="hslValueDiv" type="text" readonly="readonly"/>
                </div>
            </div>
        </div>
        <script>
            var c = document.getElementById("canvas");
            var ctx = c.getContext("2d");
            var colorDiv = document.getElementById("colorDiv");
            var hexadecimalValueDiv = document.getElementById("hexadecimalValueDiv");
            var rgbValueDiv = document.getElementById("rgbValueDiv");
            var hslValueDiv = document.getElementById("hslValueDiv");
            var hexadecimalTipDiv = document.getElementById("hexadecimalTipDiv");
            var saturationTipDiv = document.getElementById("saturationTipDiv");
            var saturationRange = document.getElementById("saturationRange");
            var luminanceTipDiv = document.getElementById("luminanceTipDiv");
            var luminanceRange = document.getElementById("luminanceRange");

            //十字光标颜色
            var crossCursorColor = "black";
            //十字光标线宽
            var crossCursorLineWidth = 2;
            //十字光标某一边线段长
            var crossCursorHalfLineLen = 5;
            //十字光标中间断裂处长度
            var crossCursorHalfBreakLineLen = 2;

            //画布中心点X坐标
            var centerX = c.width / 2;
            //画布中心点Y坐标
            var centerY = c.height / 2;
            //缩放绘制比例
            var scaleRate = 10;
            //画布的内切圆半径(之所以减去一个数是为了可以显示完整的十字光标)
            var innerRadius = Math.min(centerX, centerY) - crossCursorHalfLineLen - crossCursorHalfBreakLineLen;
            //内切圆半径的平方
            var pow2InnerRadius = Math.pow(innerRadius, 2);
            //缩放绘制时的绘制半径,即画布的外径除以缩放比例
            var scaledRadius = Math.sqrt(Math.pow(c.width / 2, 2) + Math.pow(c.height / 2, 2)) / scaleRate;
            //由于该圆是由绕圆心的多条线段组成,该值表示将圆分割的份数
            var count = 360;
            //一整个圆的弧度值
            var doublePI = Math.PI * 2;
            //由于圆心处是多条线段的交汇点,Composite是source-over模式,所以后绘制的线段会覆盖前一个线段。另外由于采用线段模拟圆,英雌
            var deprecatedRadius = innerRadius * 0.3;
            //废弃圆半径的平方
            var pow2DeprecatedRadius = Math.pow(deprecatedRadius, 2);

            //色相(0-360)
            var hue;
            //饱和度(0%-100%)
            var saturation; 
            //亮度luminance或明度lightness(0%-100%)
            var luminance;

            //当前色相位置X坐标
            var currentHuePosX = centerX + innerRadius - 1;
            //当前色相位置Y坐标
            var currentHuePosY = centerY;

            //填充圆
            function fillCircle(cx, cy, r, color) 
                ctx.fillStyle = color;
                ctx.beginPath();
                ctx.arc(cx, cy, r, 0, doublePI);
                ctx.fill();
            

            //绘制线条
            function strokeLine(x1, y1, x2, y2) 
                ctx.beginPath();
                ctx.moveTo(x1, y1);
                ctx.lineTo(x2, y2);
                ctx.stroke();
            

            //将整数转为16进制,至少保留2位
            function toHexString(intValue) 
                var str = intValue.toString(16);
                if(str.length == 1) 
                    str = "0" + str;
                
                return str;
            

            //判断坐标(x,y)是否在合法的区域内
            function isInValidRange(x, y) 
                var pow2Distance = Math.pow(x-centerX, 2) + Math.pow(y-centerY, 2);
                return pow2Distance >= pow2DeprecatedRadius && pow2Distance <= pow2InnerRadius;
            

            //绘制十字光标
            function strokeCrossCursor(x, y) 
                ctx.globalCompositeOperation = "source-over";
                ctx.strokeColor = crossCursorColor;
                ctx.lineWidth = crossCursorLineWidth;
                strokeLine(x, y-crossCursorHalfBreakLineLen, x, y-crossCursorHalfBreakLineLen-crossCursorHalfLineLen);
                strokeLine(x, y+crossCursorHalfBreakLineLen, x, y+crossCursorHalfBreakLineLen+crossCursorHalfLineLen);
                strokeLine(x-crossCursorHalfBreakLineLen, y, x-crossCursorHalfBreakLineLen-crossCursorHalfLineLen, y);
                strokeLine(x+crossCursorHalfBreakLineLen, y, x+crossCursorHalfBreakLineLen+crossCursorHalfLineLen, y);
            

            //将对象中的hsl分量组成一个hsl颜色(h在0到360之间,s与l均在0到1之间)
            function formHslColor(obj) 
                return "hsl(" + obj.h + "," + Math.round(obj.s * 1000)/10 + "%," + Math.round(obj.l * 1000)/10 + "%)"; 
            

            //将对象中的rgb分量组成一个rgb颜色(r,g,b在0到255之间)
            function formRgbColor(obj) 
                return "rgb(" + [obj.r, obj.g, obj.b].join(",") + ")";
            

            //从画布的某点获取存储RGB的对象
            function getRgbObj(x, y) 
                var w = 1;
                var h = 1;
                var imgData = ctx.getImageData(x,y,w,h);
                var obj = 
                    r: imgData.data[0],
                    g: imgData.data[1],
                    b: imgData.data[2],
                    a: imgData.data[3]
                
                return obj;
            

            //将rgb转换为hsl对象()
            function rgbToHslObj(r, g, b) 
                r /= 255;
                g /= 255;
                b /= 255;
                var max = Math.max(r, g, b);
                var min = Math.min(r, g, b);
                var diff = max - min;
                var twoValue = max + min;
                var obj = h:0, s:0, l:0;
                if(max == min) 
                    obj.h = 0;
                 else if(max == r && g >= b) 
                    obj.h = 60 * (g - b) / diff;
                 else if(max == r && g < b) 
                    obj.h = 60 * (g - b) / diff + 360;
                 else if(max == g) 
                    obj.h = 60 * (b - r) / diff + 120;
                 else if(max == b) 
                    obj.h = 60 * (r - g) / diff + 240;
                
                obj.l = twoValue / 2;
                if(obj.l == 0 || max == min) 
                    obj.s = 0;
                 else if(0 < obj.l && obj.l <= 0.5) 
                    obj.s = diff / twoValue;
                    //obj.s = diff / (2 * obj.l);
                 else 
                    obj.s = diff / (2 - twoValue);
                    //obj.s = diff / (2 - 2 * obj.l);
                
                obj.h = Math.round(obj.h);
                return obj;
            

            //创建Hue颜色圆环
            function createHueRing() 
                ctx.globalCompositeOperation = "source-over";
                ctx.clearRect(0,0,c.width,c.height);
                ctx.save();
                //将绘制原点移动到画布中心
                ctx.translate(centerX, centerY);
                //将画布放大相应比例,restore后,绘制内容会缩小
                ctx.scale(scaleRate, scaleRate);
                for(var i=0; i<count; i++) 
                    var degree = i / count * 360;
                    var radian = Math.PI * degree / 180;
                    var x = scaledRadius * Math.cos(radian);
                    var y = scaledRadius * Math.sin(radian);
                    ctx.lineWidth=1;
                    ctx.strokeStyle = "hsl(" + degree +"," + saturation + "," + luminance + ")";
                    ctx.beginPath();
                    ctx.moveTo(x, y);
                    ctx.lineTo(0,0);
                    ctx.stroke();
                
                ctx.restore();
                ctx.globalCompositeOperation = "destination-out";
                fillCircle(centerX, centerY, deprecatedRadius, "black");

                ctx.globalCompositeOperation = "destination-in";
                fillCircle(centerX, centerY, innerRadius, "black");
            

            //点击canvas中的Hue拾色圈
            function onCanvasClick() 
                var x = event.offsetX;
                var y = event.offsetY;
                if(!isInValidRange(x, y)) 
                    return;
                
                currentHuePosX = x;
                currentHuePosY = y;
                //创建hue背景圆环
                createHueRing();
                setColorValue(x, y);
                strokeCrossCursor(x, y);
            

            function setColorValue(x, y) 
                //获取包含rgb的颜色对象
                var rgbObj = getRgbObj(x, y);
                var rgbColor = formRgbColor(rgbObj);
                colorDiv.style.backgroundColor = rgbColor;
                rgbValueDiv.value = rgbColor;
                var hex = "#" + toHexString(rgbObj.r) + toHexString(rgbObj.g) + toHexString(rgbObj.b);
                hexadecimalValueDiv.value = hex;

                var hslObj = rgbToHslObj(rgbObj.r, rgbObj.g, rgbObj.b);
                hslValueDiv.value = formHslColor(hslObj);
                hueTipDiv.innerHTML = ("Hue:" + hslObj.h);
            

            function onHSLRangeChange() 
                //event.target.value;
                saturation = saturationRange.value + "%";
                luminance = luminanceRange.value + "%";
                saturationTipDiv.innerHTML = ("Saturation:" + saturation);
                luminanceTipDiv.innerHTML = ("Luminance:" + luminance);
                createHueRing();
                setColorValue(currentHuePosX, currentHuePosY)
                strokeCrossCursor(currentHuePosX, currentHuePosY);
            

            function init() 
                c.addEventListener("click", onCanvasClick);
                onHSLRangeChange();
            

            init();

        </script>
    </body>
</html>

有几个缺陷:
- 不能根据颜色值来设置HSL。
- 由于HSL的值是根据从Hue环形调色板中取出的RGB颜色值换算为HSL的,因此跟滑动条上的值可能会有出入(如果是5舍6入那就一样了)

以上是关于VB中HSL怎么转换为RGB?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Objective C 从 RGB 转换为 HSL

将 Hsl 转换为 rgb 和 hex

如何将 RGB 颜色转换为 HSV?

用MATLAB编写RGB到HSL和HSL到RGB颜色空间的转换程序:rgb2hsl.m和hsl2rgb.m

Atitit  从 RGB 到 HSL 或 HSV 的转换

C++のeasyx5:函数BGRGetBValueGetGValueGetRValue的运用