Наложение формулы режима наложения? - PullRequest
6 голосов
/ 29 апреля 2011

У меня есть 2 цвета: один динамически установлен, а другой всегда белый 0.5 альфа. Я хочу рассчитать полученный белый цвет, как если бы он был нарисован поверх динамического цвета в режиме наложения Overlay.

Я знаю, что Наложение сочетает в себе Умножение и Экран режимы наложения.

Формула режима умножения смешивания:

Result Color = (Top Color) * (Bottom Color) /255

В то время как режим наложения экрана:

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

Как рассчитать результирующий цвет для режима наложения Overlay?

Существует ли класс расширения UIColor, который делает это из коробки?

Ответы [ 3 ]

7 голосов
/ 29 апреля 2011

В ответ на ответ Вилли , формула перенесена в код:

CGFloat newComponents[4];
const CGFloat *topComponents = CGColorGetComponents([[UIColor colorWithRed:1 green:1 blue:1 alpha:1] CGColor]);
const CGFloat *components = CGColorGetComponents(self.color.CGColor);
const int n = CGColorGetNumberOfComponents(self.color.CGColor);

for(int i=0; i < n; i++) {

    if(components[i] > 0.5) {
        CGFloat value = (topComponents[i]-components[i])/0.5;
        CGFloat min = components[i]-(topComponents[i]-components[i]);
        newComponents[i] = topComponents[i]*value+min; 
    } else {
        CGFloat value = components[i]/0.5;
        newComponents[i] = topComponents[i]*value; 
    }
}

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UIColor *resultColor = [UIColor colorWithCGColor:CGColorCreate(colorSpace, newComponents)];
CGColorSpaceRelease(colorSpace);
7 голосов
/ 29 апреля 2011

Формула состоит из двух частей:

Первая часть: Если значение нижнего уровня> 127,5, выполните следующее -

Единица значения = (значение нижнего уровня 255) /127,5

Минимальное значение = Значение нижнего уровня - (255-Значение нижнего уровня)

Наложение = (Значение верхнего уровня * Единица измерения) + Минимальное значение

Вторая часть: Если нижний уровеньЗначение <127,5, затем выполните следующее - </p>

Единица значения = Значение нижнего уровня / 127,5

Наложение = Значение верхнего слоя * Единица значения

Из формул мы видим, чтоконечный результат во многом зависит от значения верхнего слоя.Если значение верхнего слоя выше (светлее), то конечный результат с большей вероятностью будет светлее.

С здесь .

2 голосов
/ 29 апреля 2011

Я понятия не имею о вашей цели, и, возможно, совершенно не по теме, но почему бы просто не использовать Quartz 2D?

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetBlendMode(ctx, kCGBlendModeOverlay);
... draw with overlay blending

CGBlendMode предлагает через CGContextSetBlendMode Наложение, Умножение, Экран и многое другое ...:

enum CGBlendMode {
    /* Available in Mac OS X 10.4 & later. */
    kCGBlendModeNormal,
    kCGBlendModeMultiply,
    kCGBlendModeScreen,
    kCGBlendModeOverlay,
    kCGBlendModeDarken,
    kCGBlendModeLighten,
    kCGBlendModeColorDodge,
    kCGBlendModeColorBurn,
    kCGBlendModeSoftLight,
    kCGBlendModeHardLight,
    kCGBlendModeDifference,
    kCGBlendModeExclusion,
    kCGBlendModeHue,
    kCGBlendModeSaturation,
    kCGBlendModeColor,
    kCGBlendModeLuminosity,

    /* Available in Mac OS X 10.5 & later. R, S, and D are, respectively,
       premultiplied result, source, and destination colors with alpha; Ra,
       Sa, and Da are the alpha components of these colors.

       The Porter-Duff "source over" mode is called `kCGBlendModeNormal':
         R = S + D*(1 - Sa)

       Note that the Porter-Duff "XOR" mode is only titularly related to the
       classical bitmap XOR operation (which is unsupported by
       CoreGraphics). */

    kCGBlendModeClear,          /* R = 0 */
    kCGBlendModeCopy,           /* R = S */
    kCGBlendModeSourceIn,       /* R = S*Da */
    kCGBlendModeSourceOut,      /* R = S*(1 - Da) */
    kCGBlendModeSourceAtop,     /* R = S*Da + D*(1 - Sa) */
    kCGBlendModeDestinationOver,    /* R = S*(1 - Da) + D */
    kCGBlendModeDestinationIn,      /* R = D*Sa */
    kCGBlendModeDestinationOut,     /* R = D*(1 - Sa) */
    kCGBlendModeDestinationAtop,    /* R = S*(1 - Da) + D*Sa */
    kCGBlendModeXOR,            /* R = S*(1 - Da) + D*(1 - Sa) */
    kCGBlendModePlusDarker,     /* R = MAX(0, (1 - D) + (1 - S)) */
    kCGBlendModePlusLighter     /* R = MIN(1, S + D) */
};
typedef enum CGBlendMode CGBlendMode; /* Available in Mac OS X 10.4 & later. */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...