2012-04-23 18 views
6

Estoy tratando de convertir una función para crear un círculo HSV de Delphi a C#, pero el resultado no es el correcto.Convertir código de círculo HSV de Delphi a C#

Mi objetivo es hacer una aplicación para Windows Phone 7, y solo estoy usando el SDK WP7.1, más la biblioteca WriteableBitmapEx.

Delphi Code:

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.Brush.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,S,V) 
      END 
     END; 
    END; 
END; 

FUNCTION HSVtoRGBTriple(CONST H,S,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) // achromatic: shades of gray 
    ELSE 
    BEGIN        // chromatic 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, V, p); 
      2: RESULT := RGBtoRGBTriple(p, V, t); 
      3: RESULT := RGBtoRGBTriple(p, q, V); 
      4: RESULT := RGBtoRGBTriple(t, p, V); 
      5: RESULT := RGBtoRGBTriple(V, p, q); 
     ELSE 
      RESULT := RGBtoRGBTriple(0,0,0) // should never happen; 
              // avoid compiler warning 
     END 
    END 
END 

Los resultados de código de Delphi:

delphi img

Mi código 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, d, a); 
       case 2: return Color.FromArgb(RGB_MAX, a, d, c); 
       case 3: return Color.FromArgb(RGB_MAX, a, b, d); 
       case 4: return Color.FromArgb(RGB_MAX, c, a, d); 
       case 5: return Color.FromArgb(RGB_MAX, d, a, b); 
       default: return Color.FromArgb(RGB_MAX, 0, 0, 0); 
      } 
     } 
     else 
     { 
      byte d = (byte)(v * RGB_MAX); 
      return Color.FromArgb(255, d, d, d); 
     } 
    } 

    public static Color HsvToRgb(HSV hsv) 
    { 
     return HsvToRgb(hsv.h, hsv.s, hsv.v); 
    }  

Mi C# resultado:

csharp

¿Qué estoy haciendo mal?

Gracias de antemano.

editado con solución

Con la gran respuesta de @Aybe, podría hacer una versión de trabajo del HSV Whell.

Este es el código de trabajo para 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); 
    } 

Y ahora, el nuevo resultado:

okimg

Gracias!

+4

Compruebe su Math.atan2 (y, x). Debería ser Math.Atan2 (x, y) –

+0

@BasePointer gracias por su sugerencia, pero esto no solucionó. –

+2

La versión C# se ve mucho más fría –

Respuesta

4

Después de pasar una hora o así, he aprendido algunas cosas en el proceso ...

Ahora el código: (funciona para cualquier tamaño)

Ésta es HSL pero le dio la url donde tienes otros algos

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, 96, PixelFormats.Bgr32, null); 
      bitmap.WritePixels(new Int32Rect(0, 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, saturation, lightness); 
        pixels[y*width + x] = 0xFF << 24 | rgb.R << 16 | rgb.G << 8 | rgb.B; 
       } 
      } 
      return BitmapSource.Create(width, height, 96, 96, 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 saturation, 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, 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); 
     } 
    } 
} 
+1

Gracias @Aybe, tu código funcionó muy bien, solo tuve que hacer algunos ajustes para ser posible usar con WP7 SDK. –

+0

también, basado en su solución para HSL, intentaré hacer una versión HSV. Si puedo hacerlo, publicaré la solución más tarde. –

+0

Bien, aquí está el algo de HSV a RGB http://www.easyrgb.com/index.php?X=MATH&H=21#text21. – Aybe

0

¿No es la profundidad de bits en los dispositivos WP7 de 16 bits por defecto? En mi Omnia 7 es. Hay una configuración de registro que controla este parámetro pero puede no estar disponible en todos los teléfonos, en su lugar debe oscilar los colores de 24 bits a 16 bits, estará disponible en todos los teléfonos. Sugiero que eche un vistazo a Microsoft.Xna.Framework.Graphics.PackedVector, hay constructores como BGR565 que aceptan flotadores como entrada. Y para todas sus necesidades de conversión de color: http://www.easyrgb.com/, prácticamente todos los algoritmos están ahí para convertir espacios de color.

+1

Es, pero ese no es el problema, el código convertido tiene problemas (flotantes, de sujeción, etc.). Agregar '

+0

Acabo de echarle un vistazo más profundo :-) – Aybe