Pregunta

Estoy intentando emular el Tinte Efecto de XML abiertos. Lo que hace es cambiar la tonalidad de los píxeles de una imagen cambiando la tonalidad. Se tarda 2 parámetros: 1) el hue (en grados) y 2) la amt (la cantidad, un porcentaje). Es # 2 que estoy teniendo problemas con. Los estados de especificaciones:

  

Tint : Cambia los valores de color de efecto ya sea hacia o lejos de tonalidad por el   cantidad especificada.

     
      
  • AMT (Cantidad) -. Especifica por cuánto se desplaza el valor del color
  •   
  • tonalidad (Hue) -. Especifica el matiz hacia el que para teñir
  •   

Nunca ocupándose de la construcción XML, que puede emular los valores que tienen un amt de 100%. Así, por ejemplo, si quiero Azul (matiz: 240 °), puedo crear esto (el Tinted una). He aquí un ejemplo:

ORIGINAL y Tinted (hue = 240, Monto = 100%).
original modificado

Esto se logra simplemente poniendo el tono a 240, manteniendo la saturación y luminancia de la misma y la conversión de RGB y escribir cada píxel.

Esto es lo que no se puede lograr sin embargo:

Hue = 240 ( azul ), la cantidad = 30% , 50% y 80% , respectivamente
30% 50% 80%

Una vez más, la especificación de Amount dice especifica por cuánto se desplaza el valor del color . He intentado todo tipo de formas aquí para conseguir que esto funcione, pero parece que no puede (hue=hue*amount, originalhue * amount + hue, etc.)

Más ejemplos: Hue = 120 ( verde ), la cantidad = 30% , 50 % , 80% y 100% , respectivamente. La 100% que puedo conseguir.
30% 50% 80% 100%

Aquí están algunas listas de valores de un solo píxel en las imágenes de arriba:

Pixel 159, 116 - Azul Fotos

        Hue    Amount    R    G    B    | H    S     L
Original                 244  196   10  |  48  0.92  0.5
Blue    240     30%      237   30   45  | 356  0.85  0.52
Blue    240     50%      245    9  156  | 323  0.93  0.5
Blue    240     80%      140   12  244  | 273  0.91  0.5
Blue    240    100%       12   12  244  | 240  0.91  0.5

Pixel 159, 116 - Verde Fotos

        Hue    Amount    R    G    B    | H    S     L
Original                 244  196   10  |  48  0.92  0.5
Green    120     30%     211  237   30  |  68  0.85  0.52
Green    120     50%     159  237   30  |  83  0.85  0.52
Green    120     80%      81  237   29  | 105  0.85  0.52
Green    120    100%      29  237   29  | 120  0.85  0.52


Entonces, la pregunta es:? ¿Alguien sabe cómo se debe trabajar

  

Nota: Este es no un duplicado de:

     
¿Fue útil?

Solución

Estoy seguro de que los resultados de problemas de la forma en que se interpolación ángulos. Aquí está una función de interpolación (escrito en Python) que debe hacer el truco. Se basa en una sugerencia de la rosca foros de XNA más corta interpolación ángulo 2D .

def wrap(value, lower, upper):
    distance = upper - lower
    return value - ((value-lower)//distance)*distance

def shortestangle(a,b):
    angle = wrap(b-a, 0, 360)
    if angle>=180: angle -= 360
    return angle

def interpolate(a,b,amount):
    return (a+shortestangle(a,b)*amount)%360

Ahora, interpolate(originalHue,hue,amount) debe producir el resultado deseado.

Editar: Es mi entendimiento de que su objetivo es hacer girar la tonalidad original, hacia una cierta tonalidad de destino por alguna cantidad dada. Estoy seguro de que ya está familiarizado con esto, pero en aras de la ilustración, he aquí una rueda de color.

rueda de color
(fuente: sapdesignguild.org )

El problema es que la mezcla (o de interpolación) dos ángulos no es trivial, por lo que un código como hue = ((hue - originalHue) * amount) + originalHue no funcionará. Hay un número infinito de maneras de ir de un ángulo a otro a causa de la envolvente a 360 °. Para llegar desde 0 ° a 60 ° se podía girar 60 ° en sentido antihorario, 420 ° en sentido antihorario, 300 ° en sentido horario, etc. Por lo general, el ángulo más corto es el que desee uno.

Por ejemplo, vamos a considerar los cuellos de pingüino: si su tonalidad original es 30 ° (naranja), su objetivo es 240 ° (azul) y la cantidad es del 50%, se llega a los siguientes resultados:

//Linear Interpolation
(30° + (240° - 30°)*0.5) = 135° (green)

//"Shortest 2D Angle Interpolation"
(30° + shortestangle(30°,240°)*0.5) % 360 = (30° + (-150°)*0.5) % 360 = 315° (magenta)

Mi conjetura es que el segundo resultado es el que usted está buscando, pero puedo estar equivocado y el error podría ser un lugar completamente distinto ...

Otros consejos

Se debe echar un vistazo a TintParams en GDI + (no forma parte de .NET sin embargo) -. esto puede ser justo lo que está buscando

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top