将HSV循环代码从Delphi转换为C#

将HSV循环代码从Delphi转换为C#,第1张

概述我正在尝试将函数转换为从Delphi到C#创建HSV Circle,但结果并不正确. 我的目标是为Windows Phone 7做一个应用程序,我只使用WP7.1 SDK和WriteableBitmapEx库. 德尔福代码: FUNCTION CreateHueSaturationCircle(CONST size: INTEGER; CONST ValueLevel: INTEGER; CONS 我正在尝试将函数转换为从Delphi到C#创建HSV Circle,但结果并不正确.

我的目标是为Windows Phone 7做一个应用程序,我只使用WP7.1 SDK和writeablebitmapex库.

德尔福代码:

FUNCTION CreateHueSaturationCircle(CONST size: INTEGER; CONST ValueLevel: INTEGER; CONST Backgroundcolor: Tcolor): TBitmap;VAR  dSquared: INTEGER;  H,S,V: INTEGER;  i: INTEGER;  j: INTEGER;  Radius: INTEGER;  RadiusSquared: INTEGER;  row: pRGBTripleArray;  X: INTEGER;  Y: INTEGER;BEGIN    RESulT := TBitmap.Create;    RESulT.PixelFormat := pf24bit;    RESulT.WIDth := size;    RESulT.Height := size;    // Fill with background color    RESulT.Canvas.B@R_301_6678@.color := BackGroundcolor;    RESulT.Canvas.FillRect(RESulT.Canvas.ClipRect);    Radius := size div 2;    RadiusSquared := Radius * Radius;    V := ValueLevel;    FOR j := 0 TO RESulT.Height - 1 DO    BEGIN        Y := Size - 1 - j - Radius;  {Center is Radius offset}        row := RESulT.Scanline[Size - 1 - j];        FOR i := 0 TO RESulT.WIDth - 1 DO        BEGIN            X := i - Radius;            dSquared := X * X + Y * Y;            IF dSquared <= RadiusSquared THEN            BEGIN                S := ROUND((255 * SQRT(dSquared)) / Radius);                H := ROUND(180 * (1 + ArcTan2(X,Y) / PI));   // 0..360 degrees                // Shift 90 degrees so H=0 (red) occurs along "X" axis                H := H + 90;                IF H > 360 THEN                    H := H - 360;                row[i] := HSVtoRGBTriple(H,V)            END        END;    END;END;FUNCTION HSVtoRGBTriple(CONST H,V: INTEGER): TRGBTriple;CONST  divisor: INTEGER = 255 * 60;VAR  f: INTEGER;  hTemp: INTEGER;  p,q,t: INTEGER;  VS: INTEGER;BEGIN    IF S = 0 THEN        RESulT := RGBtoRGBTriple(V,V,V)  // a@R_652_4048@:  shades of gray    ELSE    BEGIN                              // @R_652_4048@ color        IF H = 360 THEN            hTemp := 0        ELSE            hTemp := H;        f := hTemp MOD 60;     // f is IN [0,59]        hTemp := hTemp div 60;     // h is Now IN [0,6)        VS := V * S;        p := V - VS div 255;                 // p = v * (1 - s)        q := V - (VS*f) div divisor;         // q = v * (1 - s*f)        t := V - (VS*(60 - f)) div divisor;  // t = v * (1 - s * (1 - f))        CASE hTemp OF            0:   RESulT := RGBtoRGBTriple(V,t,p);            1:   RESulT := RGBtoRGBTriple(q,p);            2:   RESulT := RGBtoRGBTriple(p,t);            3:   RESulT := RGBtoRGBTriple(p,V);            4:   RESulT := RGBtoRGBTriple(t,p,V);            5:   RESulT := RGBtoRGBTriple(V,q);        ELSE            RESulT := RGBtoRGBTriple(0,0)  // should never happen;                                          // avoID compiler warning        END    ENDEND

Delphi代码的结果:

我的C#代码:

public struct HSV    {        public float h;        public float s;        public float v;    }    public voID createHsvCircle()    {        int size = 300;        wb = new WriteableBitmap(size,size);        wb.Clear(GraphicsUtils.Whitecolor);        int radius = size / 2;        int radiusSquared = radius * radius;        int x;        int y;        int dSquared;        HSV hsv;        hsv.v = 255F;        for (int j = 0; j < size; j++)        {            y = size - 1 - j - radius;            for (int i = 0; i < size; i++)            {                x = i - radius;                dSquared = x * x + y * y;                if (dSquared <= radiusSquared)                {                    hsv.s = (float) Math.Round((255 * Math.Sqrt(dSquared)) / radius);                    hsv.h = (float) Math.Round(180 * (1 + Math.atan2(y,x) / Math.PI));                    hsv.h += 90;                    if (hsv.h > 360)                    {                        hsv.h -= 360;                    }                    color color = GraphicsUtils.HsvToRgb(hsv);                    wb.SetPixel(i,j,color);                }            }        }        wb.InvalIDate();    }    public static color HsvToRgb(float h,float s,float v)    {        h = h / 360;        if (s > 0)        {            if (h >= 1)                h = 0;            h = 6 * h;            int hueFloor = (int)Math.Floor(h);            byte a = (byte)Math.Round(RGB_MAX * v * (1.0 - s));            byte b = (byte)Math.Round(RGB_MAX * v * (1.0 - (s * (h - hueFloor))));            byte c = (byte)Math.Round(RGB_MAX * v * (1.0 - (s * (1.0 - (h - hueFloor)))));            byte d = (byte)Math.Round(RGB_MAX * v);            switch (hueFloor)            {                case 0: return color.FromArgb(RGB_MAX,d,c,a);                case 1: return color.FromArgb(RGB_MAX,b,a);                case 2: return color.FromArgb(RGB_MAX,a,c);                case 3: return color.FromArgb(RGB_MAX,d);                case 4: return color.FromArgb(RGB_MAX,d);                case 5: return color.FromArgb(RGB_MAX,b);                default: return color.FromArgb(RGB_MAX,0);            }        }        else        {            byte d = (byte)(v * RGB_MAX);            return color.FromArgb(255,d);        }    }    public static color HsvToRgb(HSV hsv)    {        return HsvToRgb(hsv.h,hsv.s,hsv.v);    }

我的c#结果:

我做错了什么?

提前致谢.

用解决方案编辑

有了@Aybe的精彩答案,我可以从HSV做一个工作版本.

这是WP7 SDK的工作代码:

public const double PI = 3.14159265358979323846264338327950288d;    public voID createHsvCircle(double value = 1.0d)    {        if (value < 0.0d || value > 1.0d)            throw new ArgumentOutOfRangeException("value");        var size = 1024;        wb = new WriteableBitmap(size,size);        // fill with white.        var white = colors.White;        for (int index = 0; index < wb.Pixels.Length; index++)        {            wb.Pixels[index] = 0xFF << 24 | white.R << 16 | white.G << 8 | white.B;        }        var cx = size / 2;        var cy = size / 2;        var radius = cx;        var radiusSquared = radius * radius;        for (int i = 0; i < size; i++)        {            for (int j = 0; j < size; j++)            {                var x = i - cx;                var y = j - cy;                var distance = (double)x * x + y * y;                if (distance <= radiusSquared) // In circle                {                    var angle = 180.0d * (1 + Math.atan2(x,y) / PI);                    // shift 90 degrees so H=0 (red) occurs along "X" axis                    angle += 90.0d;                    if (angle > 360.0d)                    {                        angle -= 360.0d;                    }                    var hue = angle / 360.0d; // hue must be into 0 to 1.                    var saturation = Math.Sqrt(distance) / radius; // saturation must be into 0 to 1.                    var hsv = new HSV(hue,saturation,value);                    var rgb = RGB.FromHsv(hsv.H,hsv.S,hsv.V);                    wb.Pixels[j * size + i] = 0xFF << 24 | rgb.R << 16 | rgb.G << 8 | rgb.B;                }            }        }        wb.InvalIDate();    }    public static RGB FromHsv(double hue,double saturation,double value)    {        if (hue < 0.0d || hue > 1.0d)            throw new ArgumentOutOfRangeException("hue");        if (saturation < 0.0d || saturation > 1.0d)            throw new ArgumentOutOfRangeException("saturation");        if (value < 0.0d || value > 1.0d)            throw new ArgumentOutOfRangeException("value");        if (saturation == 0.0d)        {            var b1 = (byte)(value * 255);            return new RGB(b1,b1,b1);        }        double r;        double g;        double b;        var h = hue * 6.0d;        if (h == 6.0d)        {            h = 0.0d;        }        int i = (int)Math.Floor(h);        var v1 = value * (1.0d - saturation);        var v2 = value * (1.0d - saturation * (h - i));        var v3 = value * (1.0d - saturation * (1.0d - (h - i)));        switch (i)        {            case 0:                r = value;                g = v3;                b = v1;                break;            case 1:                r = v2;                g = value;                b = v1;                break;            case 2:                r = v1;                g = value;                b = v3;                break;            case 3:                r = v1;                g = v2;                b = value;                break;            case 4:                r = v3;                g = v1;                b = value;                break;            default:                r = value;                g = v1;                b = v2;                break;        }        r = r * 255.0d;        if (r > 255.0d)        {            r = 255.0d;        }        g = g * 255.0d;        if (g > 255.0d)        {            g = 255.0d;        }        b = b * 255.0d;        if (b > 255.0d)        {            b = 255.0d;        }        return new RGB((byte)r,(byte)g,(byte)b);    }

而现在,新的结果:

谢谢!

解决方法 花了一个小时左右后,我在这个过程中学到了一些东西……

现在代码:(适用于任何规模)

这是HSL,但是我给你了你有其他算法的网址.

using System;using System.Diagnostics;using System.Runtime.InteropServices;using System.windows;using System.windows.Media;using System.windows.Media.Imaging;namespace colorWheel{    /// <summary>    ///   Interaction logic for MainWindow.xaml    /// </summary>    public partial class MainWindow : Window    {        public MainWindow()        {            InitializeComponent();        }        private voID BuilDWheel()        {            var wIDth = 1024;            var height = wIDth;            var cx = wIDth/2;            var cy = height/2;            var colors = new int[wIDth*height];            var gray = colors.Gray.ToBgr32();            for (int index = 0; index < colors.Length; index++) colors[index] = gray;            var radius = cx;            var radiusSquared = radius*radius;            for (int i = 0; i < height; i++)            {                for (int j = 0; j < wIDth; j++)                {                    var x = j - cx;                    var y = i - cy;                    var distanceSquared = (double) x*x + y*y;                    if (distanceSquared <= radiusSquared) // In circle                    {                        var h = Math.atan2(x,y).Todegrees() + 180.0d; // Angle                        var s = 1.0d;                        var l = (1.0d - ((1.0d/radiusSquared)*distanceSquared)); // 1 - (distance normalized)                        var hsl = new HSL((float) h,(float) s,(float) l);                        var rgb = RGB.FromHsl(hsl.H,hsl.S,hsl.L);                        colors[i*wIDth + j] = rgb.R << 16 | rgb.G << 8 | rgb.B;                    }                }            }            var bitmap = new WriteableBitmap(wIDth,height,96,PixelFormats.Bgr32,null);            bitmap.WritePixels(new Int32Rect(0,wIDth,height),colors,wIDth*4,0);            image.source = bitmap;        }        private voID Window_Loaded(object sender,RoutedEventArgs e)        {            BuilDWheel();        }    }    public static class Helpers    {        public static double Todegrees(this double radians)        {            return radians*57.2957795130823; // radians * (180.0d / Math.PI)        }        public static double Toradians(this double degrees)        {            return degrees*0.0174532925199433; // degrees * (Math.PI / 180.0d)        }    }    public static class colorExtensions    {        public static color FromBgr32(this Int32 color)        {            return color.Fromrgb((byte) ((color & 0xFF0000) >> 16),(byte) ((color & 0xFF00) >> 8),(byte) (color & 0xFF));        }        public static int ToBgr32(this color color)        {            return color.R << 16 | color.G << 8 | color.B;        }    }    /// <summary>    ///   Represents a color in an HSL space.    /// </summary>    [StructLayout(LayoutKind.Sequential)]    public struct HSL    {        [DeBUGgerbrowsable(DeBUGgerbrowsableState.Never)] private Readonly double _h;        [DeBUGgerbrowsable(DeBUGgerbrowsableState.Never)] private Readonly double _s;        [DeBUGgerbrowsable(DeBUGgerbrowsableState.Never)] private Readonly double _l;        /// <summary>        ///   Returns the fully qualifIEd type name of this instance.        /// </summary>        /// <returns> A <see cref="T:System.String" /> containing a fully qualifIEd type name. </returns>        /// <filterpriority>2</filterpriority>        public overrIDe string ToString()        {            return string.Format("H: {0},S: {1},L: {2}",_h,_s,_l);        }        /// <summary>        ///   Create a new instance of <see cref="HSL" /> .        /// </summary>        /// <param name="h"> Value of <see cref="H" /> component. </param>        /// <param name="s"> Value of <see cref="S" /> component. </param>        /// <param name="l"> Value of <see cref="L" /> component. </param>        public HSL(double h,double s,double l)        {            _h = h;            _s = s;            _l = l;        }        /// <summary>        ///   Gets the value of the hue component.        /// </summary>        public double H        {            get { return _h; }        }        /// <summary>        ///   Gets the value of the saturation component.        /// </summary>        public double S        {            get { return _s; }        }        /// <summary>        ///   Gets the value of the lightness component.        /// </summary>        public double L        {            get { return _l; }        }        public overrIDe bool Equals(object obj)        {            if (ReferenceEquals(null,obj)) return false;            if (obj.GetType() != typeof (HSL)) return false;            return Equals((HSL) obj);        }        public bool Equals(HSL other)        {            return other._h.Equals(_h) && other._l.Equals(_l) &&                   other._s.Equals(_s);        }        /// <summary>        ///   Create a new instance of <see cref="HSL" />,from RGB values.        /// </summary>        /// <param name="red"> Value of the red component. </param>        /// <param name="green"> Value of the green component. </param>        /// <param name="blue"> Value of the blue component. </param>        /// <returns> <see cref="HSL" /> instance created. </returns>        public static HSL FromrGB(byte red,byte green,byte blue)        {            var r1 = red/255.0d;            var g1 = green/255.0d;            var b1 = blue/255.0d;            var min = Math.Min(r1,Math.Min(g1,b1));            var max = Math.Max(r1,Math.Max(g1,b1));            var l = (max + min)/2.0d;            var s = 0.0d;            var h = 0.0d;            if (min == max)            {                h = 0.0d;                s = 0.0d;            }            else            {                if (l < 0.5d)                {                    s = (max - min)/(max + min);                }                else if (l >= 0.5d)                {                    s = (max - min)/(2.0d - max - min);                }                if (r1 == max)                {                    h = (g1 - b1)/(max - min);                }                else if (g1 == max)                {                    h = 2.0d + (b1 - r1)/(max - min);                }                else if (b1 == max)                {                    h = 4.0d + (r1 - g1)/(max - min);                }            }            h *= 60.0d;            if (h < 0.0d)                h += 360.0d;            return new HSL(h,s,l);        }        /// <summary>        ///   Returns the hash code for this instance.        /// </summary>        /// <returns> A 32-bit signed integer that is the hash code for this instance. </returns>        /// <filterpriority>2</filterpriority>        public overrIDe int GetHashCode()        {            unchecked            {                var result = _h.GetHashCode();                result = (result*397) ^ _l.GetHashCode();                result = (result*397) ^ _s.GetHashCode();                return result;            }        }        public static BitmapSource GetHslPalette(int wIDth = 360,int height = 100)        {            // Creates an HSL palette image like in Photoshop,etc ...            var pixels = new int[wIDth*height];            const double saturation = 1.0d;            for (var y = 0; y < height; y++)            {                for (var x = 0; x < wIDth; x++)                {                    var hue = (1.0d/wIDth)*x*360.0d;                    var lightness = 1.0d - ((1.0f/height)*y);                    var rgb = RGB.FromHsl(hue,lightness);                    pixels[y*wIDth + x] = 0xFF << 24 | rgb.R << 16 | rgb.G << 8 | rgb.B;                }            }            return BitmapSource.Create(wIDth,PixelFormats.Pbgra32,null,pixels,wIDth*4);        }        public static bool operator ==(HSL left,HSL right)        {            return left.Equals(right);        }        public static bool operator !=(HSL left,HSL right)        {            return !left.Equals(right);        }    }    /// <summary>    ///   Represents a color in an RGB space.    /// </summary>    [StructLayout(LayoutKind.Sequential)]    public struct RGB    {        [DeBUGgerbrowsable(DeBUGgerbrowsableState.Never)] private Readonly byte _r;        [DeBUGgerbrowsable(DeBUGgerbrowsableState.Never)] private Readonly byte _g;        [DeBUGgerbrowsable(DeBUGgerbrowsableState.Never)] private Readonly byte _b;        /// <summary>        ///   Create a new instance of <see cref="RGB" /> .        /// </summary>        /// <param name="r"> Value of red component. </param>        /// <param name="g"> Value of green component. </param>        /// <param name="b"> Value of blue component. </param>        public RGB(byte r,byte g,byte b)        {            _r = r;            _g = g;            _b = b;        }        /// <summary>        ///   Returns the fully qualifIEd type name of this instance.        /// </summary>        /// <returns> A <see cref="T:System.String" /> containing a fully qualifIEd type name. </returns>        /// <filterpriority>2</filterpriority>        public overrIDe string ToString()        {            return string.Format("R: {0},G: {1},B: {2}",_r,_g,_b);        }        /// <summary>        ///   Gets the value of the red component.        /// </summary>        public byte R        {            get { return _r; }        }        /// <summary>        ///   Gets the value of the green component.        /// </summary>        public byte G        {            get { return _g; }        }        /// <summary>        ///   Gets the value of the blue component.        /// </summary>        public byte B        {            get { return _b; }        }        public overrIDe bool Equals(object obj)        {            if (ReferenceEquals(null,obj)) return false;            if (obj.GetType() != typeof (RGB)) return false;            return Equals((RGB) obj);        }        public bool Equals(RGB other)        {            return other._b == _b && other._g == _g && other._r == _r;        }        /// <summary>        ///   Create a new instance of <see cref="RGB" />,from HSL values.        /// </summary>        /// <param name="hue"> Hue,from 0.0 to 360.0. </param>        /// <param name="saturation"> Saturation,from 0.0 to 1.0. </param>        /// <param name="lightness"> lightness,from 0.0 to 1.0. </param>        /// <returns> <see cref="RGB" /> instance created. </returns>        public static RGB FromHsl(double hue,double lightness)        {            if (hue < 0.0d || hue > 360.0d) throw new ArgumentOutOfRangeException("hue");            if (saturation < 0.0d || saturation > 1.0d) throw new ArgumentOutOfRangeException("saturation");            if (lightness < 0.0d || lightness > 1.0d) throw new ArgumentOutOfRangeException("lightness");            if (saturation == 0.0d)            {                var b1 = (byte) (lightness*255);                return new RGB(b1,b1);            }            var t2 = 0.0d;            if (lightness < 0.5d)                t2 = lightness*(1.0d + saturation);            else if (lightness >= 0.5d)                t2 = lightness + saturation - lightness*saturation;            var t1 = 2.0d*lightness - t2;            var h = hue/360.0d;            var tr = h + 1.0d/3.0d;            var tg = h;            var tb = h - 1.0d/3.0d;            tr = tr < 0.0d ? tr + 1.0d : tr > 1.0d ? tr - 1.0d : tr;            tg = tg < 0.0d ? tg + 1.0d : tg > 1.0d ? tg - 1.0d : tg;            tb = tb < 0.0d ? tb + 1.0d : tb > 1.0d ? tb - 1.0d : tb;            double r;            if (6.0d*tr < 1.0d)                r = t1 + (t2 - t1)*6.0d*tr;            else if (2.0d*tr < 1.0d)                r = t2;            else if (3.0d*tr < 2.0d)                r = t1 + (t2 - t1)*((2.0d/3.0d) - tr)*6.0d;            else                r = t1;            double g;            if (6.0d*tg < 1.0d)                g = t1 + (t2 - t1)*6.0d*tg;            else if (2.0d*tg < 1.0d)                g = t2;            else if (3.0d*tg < 2.0d)                g = t1 + (t2 - t1)*((2.0d/3.0d) - tg)*6.0d;            else                g = t1;            double b;            if (6.0d*tb < 1.0d)                b = t1 + (t2 - t1)*6.0d*tb;            else if (2.0d*tb < 1.0d)                b = t2;            else if (3.0d*tb < 2.0d)                b = t1 + (t2 - t1)*((2.0d/3.0d) - tb)*6.0d;            else                b = t1;            return new RGB((byte) (r*255),(byte) (g*255),(byte) (b*255));        }        /// <summary>        ///   Returns the hash code for this instance.        /// </summary>        /// <returns> A 32-bit signed integer that is the hash code for this instance. </returns>        /// <filterpriority>2</filterpriority>        public overrIDe int GetHashCode()        {            unchecked            {                var result = _b.GetHashCode();                result = (result*397) ^ _g.GetHashCode();                result = (result*397) ^ _r.GetHashCode();                return result;            }        }        public static bool operator ==(RGB left,RGB right)        {            return left.Equals(right);        }        public static bool operator !=(RGB left,RGB right)        {            return !left.Equals(right);        }    }}
总结

以上是内存溢出为你收集整理的将HSV循环代码从Delphi转换为C#全部内容,希望文章能够帮你解决将HSV循环代码从Delphi转换为C#所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1273461.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-08
下一篇2022-06-08

发表评论

登录后才能评论

评论列表(0条)

    保存