2012-08-25 19 views

Respuesta

0

A es el píxel de primer plano, B es el píxel de fondo, C es el nuevo píxel. H es el valor de Hue para cada píxel, S es el valor de Saturación, L es el valor de Luminancia e Y es el valor de Brillo. (No estoy seguro de cuál es la diferencia entre luminancia y brillo.

De todos modos, en el primer ejemplo, los valores Hue (H) y Saturación (S) del nuevo píxel (C) se copian del píxel de primer plano (A) mientras que el valor de brillo (Y) de la nueva pixel se toma del valor de luminancia (L) de la de píxeles de fondo (B).

+0

Gracias, esto es justo lo que necesitaba. Sin embargo, la fórmula no es tan simple después de todo, ya que el resultado fue un poco desgastado. Al final logré que funcionara con la ayuda de esto: http://www.beneaththewaves.net/Photography/Secrets_of_Photoshops_Colour_Blend_Mode_Revealed_Sort_Of.html – Castles

2

Wikipedia tiene un buen artículo sobre modos de mezcla http://en.wikipedia.org/wiki/Blend_modes

Ellos dan fórmulas para Multiplicar, modos de pantalla y superposición

Multiply 
Formula: Result Color = (Top Color) * (Bottom Color) /255 

Screen 
Formula: Result Color = 255 - [((255 - Top Color)*(255 - Bottom Color))/255] 

Overlay 
Formula: Result Color = if (Bottom Color < 128) 
    then (2 * Top Color * Bottom Color/255) 
    else (255 - 2 * (255 - Top Color) * (255 - Bottom Color)/255) 
+0

Gracias, esto me ayudó mucho a interpretar las fórmulas de WikiPedia (las revisé antes) Solo para agregar, estas fórmulas se deben ejecutar por separado para cada componente de color (para colores RGB). Esto no fue obvio para mí al menos inicialmente. – Jouni

5

Hace un tiempo invertí los modos de fusión de Photoshop diseñados.

un vistazo aquí:

http://www.kineticsystem.org/?q=node/13

Y a continuación el código que utilizo para convertir entre HSY (Tono, Saturación, Luminosidad) hacia y desde RGB (rojo, verde, azul). Photoshop usa algo llamado Hexacones para calcular la saturación.

Giovanni

/** 
* This is the formula used by Photoshop to convert a color from 
* RGB (Red, Green, Blue) to HSY (Hue, Saturation, Luminosity). 
* The hue is calculated using the exacone approximation of the saturation 
* cone. 
* @param rgb The input color RGB normalized components. 
* @param hsy The output color HSY normalized components. 
*/ 
public static void rgbToHsy(double rgb[], double hsy[]) { 

    double r = Math.min(Math.max(rgb[0], 0d), 1d); 
    double g = Math.min(Math.max(rgb[1], 0d), 1d); 
    double b = Math.min(Math.max(rgb[2], 0d), 1d); 

    double h; 
    double s; 
    double y; 

    // For saturation equals to 0 any value of hue are valid. 
    // In this case we choose 0 as a default value. 

    if (r == g && g == b) {   // Limit case. 
     s = 0d; 
     h = 0d; 
    } else if ((r >= g) && (g >= b)) { // Sector 0: 0° - 60° 
     s = r - b; 
     h = 60d * (g - b)/s; 
    } else if ((g > r) && (r >= b)) { // Sector 1: 60° - 120° 
     s = g - b; 
     h = 60d * (g - r)/s + 60d; 
    } else if ((g >= b) && (b > r)) { // Sector 2: 120° - 180° 
     s = g - r; 
     h = 60d * (b - r)/s + 120d; 
    } else if ((b > g) && (g > r)) { // Sector 3: 180° - 240° 
     s = b - r; 
     h = 60d * (b - g)/s + 180d; 
    } else if ((b > r) && (r >= g)) { // Sector 4: 240° - 300° 
     s = b - g; 
     h = 60d * (r - g)/s + 240d; 
    } else {       // Sector 5: 300° - 360° 
     s = r - g; 
     h = 60d * (r - b)/s + 300d; 
    } 

    y = R * r + G * g + B * b; 

    // Approximations erros can cause values to exceed bounds. 

    hsy[0] = h % 360; 
    hsy[1] = Math.min(Math.max(s, 0d), 1d); 
    hsy[2] = Math.min(Math.max(y, 0d), 1d); 
} 

/** 
* This is the formula used by Photoshop to convert a color from 
* HSY (Hue, Saturation, Luminosity) to RGB (Red, Green, Blue). 
* The hue is calculated using the exacone approximation of the saturation 
* cone. 
* @param hsy The input color HSY normalized components. 
* @param rgb The output color RGB normalized components. 
*/ 
public static void hsyToRgb(double hsy[], double rgb[]) { 

    double h = hsy[0] % 360; 
    double s = Math.min(Math.max(hsy[1], 0d), 1d); 
    double y = Math.min(Math.max(hsy[2], 0d), 1d); 

    double r; 
    double g; 
    double b; 

    double k; // Intermediate variable. 

    if (h >= 0d && h < 60d) {   // Sector 0: 0° - 60° 
     k = s * h/60d; 
     b = y - R * s - G * k; 
     r = b + s; 
     g = b + k; 
    } else if (h >= 60d && h < 120d) { // Sector 1: 60° - 120° 
     k = s * (h - 60d)/60d; 
     g = y + B * s + R * k; 
     b = g - s; 
     r = g - k; 
    } else if (h >= 120d && h < 180d) { // Sector 2: 120° - 180° 
     k = s * (h - 120d)/60d; 
     r = y - G * s - B * k; 
     g = r + s; 
     b = r + k; 
    } else if (h >= 180d && h < 240d) { // Sector 3: 180° - 240° 
     k = s * (h - 180d)/60d; 
     b = y + R * s + G * k; 
     r = b - s; 
     g = b - k; 
    } else if (h >= 240d && h < 300d) { // Sector 4: 240° - 300° 
     k = s * (h - 240d)/60d; 
     g = y - B * s - R * k; 
     b = g + s; 
     r = g + k; 
    } else {       // Sector 5: 300° - 360° 
     k = s * (h - 300d)/60d; 
     r = y + G * s + B * k; 
     g = r - s; 
     b = r - k; 
    } 

    // Approximations erros can cause values to exceed bounds. 

    rgb[0] = Math.min(Math.max(r, 0d), 1d); 
    rgb[1] = Math.min(Math.max(g, 0d), 1d); 
    rgb[2] = Math.min(Math.max(b, 0d), 1d); 
} 
+0

Gracias, Giovanni! Solo olvidaste poner la definición de las variables R, G, B. ¿Deberían ser R = 0.3, G = 0.59, B = 0.11? Encontré esos valores aquí: [http://dev.w3.org/fxtf/compositing-1/#blendingnonseparable](http://dev.w3.org/fxtf/compositing-1/# blendingnonseparable) –

+0

este código funciona bien, pero debe escalar los valores RGB, p. ej. rgb [0] = Color.RED.getRec()/255d; rgb [1] = Color.RED.getGreen()/255d; rgb [2] = Color.RED.getBlue()/255d; y viceversa para el resultado. – Chris

0

Estas fórmulas de mezcla de color son bastante complicado si es necesario incorporar también el canal alfa. Yo no era capaz de reproducir la mezcla de Photoshop, Gimp, pero funciona así:

Color mix_hsv(
    ColorMixMode::Enum mode, // blending mode 
    Color cd,    // destination color (bottom pixel) 
    Color cs)    // source color (top pixel) 
{ 
    // Modify the source color 
    float dh, ds, dv; // destination hsv 
    float sh, ss, sv; // source hsv 
    cd.GetHsv(dh, ds, dv); 
    cs.GetHsv(sh, ss, sv); 

    switch (mode) { 
     case HUE:  cs.InitFromHsv(sh, ds, dv); break; 
     case SATURATION: cs.InitFromHsv(dh, ss, dv); break; 
     case COLOR:  cs.InitFromHsv(sh, ss, dv); break; 
     case LUMINOSITY: cs.InitFromHsv(dh, ds, sv); break; 
    } 
    cs.A = std::min(cd.A, cs.A); 

    // Blend the modified source color onto the destination color 
    unsigned char cd_A_orig = cd.A; 
    cd = mix(NORMAL, cd, cs); // normal blending 
    cd.A = cd_A_orig; 
    return cd; 
} 

Si utiliza alfa premultiplicado, no se olvide de manejar correctamente en el código de seguridad. No pude encontrar el código para mezclar en el código fuente de Gimp, pero las imágenes resultantes son muy similares.

mezcla de color de Photoshop es claramente diferente, así que si alguien encuentra una manera de ponerla en práctica, por favor háganoslo todos sabemos: o)

Miso

Cuestiones relacionadas