
我的目标是为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#所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)