Формула режима наложения наложения?
у меня есть 2 цвета: 1 динамически установленный и другой, который всегда белый 0.5 alpha. Я хочу вычислить полученный белый цвет, как если бы он был нарисован поверх динамического цвета с помощью режима наложения.
Я знаю, что оверлея совместная умножение и режимы наложения.
Формула режима смешивания Multiply:
Result Color = (Top Color) * (Bottom Color) /255
в то время как режим смешивания экрана:
Result Color = 255 - [((255 - Top Color)*(255 - Bottom Color))/255]
Как рассчитать результирующий цвет для режима наложения наложения?
есть UIColor
класс расширения, который делает это из коробки?
3 ответов
есть две части формулы:
первая часть: если значение нижнего слоя > 127.5, то сделайте следующее -
Единица Измерения = (255-Значение Нижнего Слоя) / 127.5
Min Value = Нижнее Значение Слоя-(255-Нижнее Значение Слоя)
Overlay = (Значение Верхнего Слоя * Единица Измерения) + Min Value
вторая часть: если значение нижнего слоя
Единица Измерения=Значение Нижнего Слоя / 127.5
Overlay = Верхний Значение Слоя * Единица Измерения
из formual мы видим, что конечный результат сильно зависит от значения верхнего слоя. Если значение верхнего слоя выше (легче), то конечный результат, скорее всего, будет легче.
с здесь.
на Вилли, вот формула, портированная на код:
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);
Я понятия не имею о вашей цели, и может быть совершенно не по теме, но почему бы просто не использовать 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. */