2015-08-09 8 views
3

Я пытаюсь реализовать яркую цветовую смесь цвета в коде (думаю, C# на данный момент). Я нашел две страницы, которые говорят, как это сделать, но я не понимаю их обозначений.Как реализовать яркую цветовую смесь цвета в коде?

http://www.deepskycolors.com/archive/2010/04/21/formulas-for-Photoshop-blending-modes.html https://en.wikipedia.org/wiki/Blend_modes

ли кто-нибудь понять, как преобразовать его в код? С моего конца у меня есть два объекта Color с значениями r, g, b. Может ли кто-нибудь показать алгоритм, но используя значения r, g, b?

Благодаря

Вот мой нерабочим реализация:

using System; 
using System.Drawing; 

namespace CardMaker 
{ 
    class VividLight : ColorFilter 
    { 
     public override Color GetFilteredColor(Color p1, Color p2) 
     { 
      int newR = Math.Max(0, Math.Min(255, Convert.ToInt32(GetColor(p1.R, p2.R)))); 
      int newG = Math.Max(0, Math.Min(255, Convert.ToInt32(GetColor(p1.G, p2.G)))); 
      int newB = Math.Max(0, Math.Min(255, Convert.ToInt32(GetColor(p1.B, p2.B)))); 

      return Color.FromArgb(newR, newG, newB); 
     } 

     private static double GetColor(int c1, int c2) 
     { 
      if (c2 > 128) 
      { 
       return 256 - ((256 - c1)/(512 * (c2 - 128))); 
      } 
      else 
      { 
       return c1/(256 - 512 * c2); 
      } 
     } 
    } 
} 

ответ

0

Формула в терминах чисел с плавающей точкой в ​​[0, 1], и превратили его в [ 0255]. Вы также масштабировали константы, используемые в формуле соответственно.

Однако некоторые из этих констант имели аддитивную роль, а некоторые из них имели мультипликативную роль. То, что вы должны делать между этими случаями, отличается. Числа, которые будут добавлены, можно масштабировать, как вы это делали, но числа, которые будут умножаться, не должны (результат уже будет правильно масштабироваться, поскольку другой мультипликат (одно из значений цвета) уже будет масштабирован). Это находится в прямой аналогии с проблемами, возникающими при реализации умножения в арифметике с фиксированной точкой.

Здесь, везде вы сказали 512, вы должны сказать 2.

В качестве примечания, вы должны помнить о возможной скорости/точности компромисса между целыми числами и с плавающей точкой делением. Ваш метод говорит, что он возвращает double, но выражение в выражении return вычисляет значение int (и использует целочисленное деление, округляя вниз). Этот результат затем расширяется компилятором до двойника после оценки. Возможно, что ваши результаты будут более точными (и медленнее) с использованием деления с плавающей запятой (для этого используйте константу 2.0 вместо 2) - хотя, поскольку после вашего разделения не происходит никакого умножения, это может не быть имеют большое значение. Попробуйте это в обоих направлениях.

private static double GetColor(int c1, int c2) 
    { 
     if (c2 > 128) 
     { 
      return 256 - ((256 - c1)/(2 * (c2 - 128))); 
     } 
     else 
     { 
      return c1/(256 - 2 * c2); 
     } 
    }