Лучшие значения, чтобы сделать цвет более красным, зеленым и т. Д.?
Учитывая RGB-пиксельную карту изображения, какие будут хорошие и значимые значения, чтобы сделать изображение более красным, зеленым, синим, голубым, пурпурным или желтым?
В настоящее время в моем коде JavaScript у меня есть следующие значения изменений RGB, но мне интересно, есть ли более оптимизированные коэффициенты, основанные на теории цвета - например, для более красного цвета я использую rgb(+45,-27,-27), но я Я не уверен, например, о -27.
var strength = 45;
var strengthLess = strength - 18;
this.changeColorModes = {
'moreRed' : {r: strength, g: -strengthLess, b: -strengthLess},
'moreGreen' : {r: -strengthLess, g: strength, b: -strengthLess},
'moreBlue' : {r: -strengthLess, g: -strengthLess, b: strength},
'moreCyan' : {r: -strengthLess, g: strengthLess, b: strengthLess},
'moreMagenta' : {r: strengthLess, g: -strengthLess, b: strengthLess},
'moreYellow' : {r: strengthLess, g: strengthLess, b: -strengthLess}
};
2 ответа
Значения RGB ограничены значением 255. Так что же произойдет со значением RGB (240, 10, 10) при выполнении этой операции? Это стало бы (285, -35, -35), которое затем переполнилось бы (29, 221, 221), что, конечно, не то, что вы хотите.
В этом случае трудно дать правильное решение, потому что оно зависит от эстетики и того, какого именно эффекта вы хотите достичь. Когда графические художники корректируют цвета в программе обработки изображений, такой как Photoshop, они обычно редактируют кривые каждого канала и делают их более или менее крутыми, что является операцией умножения значений этого цветового канала. Поэтому, когда вы хотите сделать изображение "на 20% больше красного", я бы умножил все значения красного на 1,2 и установил все значения от 255 до 255, чтобы избежать переполнения. Чтобы сделать изображение "на 20% меньше голубого" (противоположно красному), я умножил бы все значения зеленого и синего на 0,8.
var pad = function(num, totalChars) {
var pad = '0';
num = num + '';
while (num.length < totalChars) {
num = pad + num;
}
return num;
};
// Ratio is between 0 and 1
var changeColor = function(color, ratio, darker) {
// Trim trailing/leading whitespace
color = color.replace(/^\s*|\s*$/, '');
// Expand three-digit hex
color = color.replace(
/^#?([a-f0-9])([a-f0-9])([a-f0-9])$/i,
'#$1$1$2$2$3$3'
);
// Calculate ratio
var difference = Math.round(ratio * 256) * (darker ? -1 : 1),
// Determine if input is RGB(A)
rgb = color.match(new RegExp('^rgba?\\(\\s*' +
'(\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])' +
'\\s*,\\s*' +
'(\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])' +
'\\s*,\\s*' +
'(\\d|[1-9]\\d|1\\d{2}|2[0-4][0-9]|25[0-5])' +
'(?:\\s*,\\s*' +
'(0|1|0?\\.\\d+))?' +
'\\s*\\)$'
, 'i')),
alpha = !!rgb && rgb[4] != null ? rgb[4] : null,
// Convert hex to decimal
decimal = !!rgb? [rgb[1], rgb[2], rgb[3]] : color.replace(
/^#?([a-f0-9][a-f0-9])([a-f0-9][a-f0-9])([a-f0-9][a-f0-9])/i,
function() {
return parseInt(arguments[1], 16) + ',' +
parseInt(arguments[2], 16) + ',' +
parseInt(arguments[3], 16);
}
).split(/,/),
returnValue;
// Return RGB(A)
return !!rgb ?
'rgb' + (alpha !== null ? 'a' : '') + '(' +
Math[darker ? 'max' : 'min'](
parseInt(decimal[0], 10) + difference, darker ? 0 : 255
) + ', ' +
Math[darker ? 'max' : 'min'](
parseInt(decimal[1], 10) + difference, darker ? 0 : 255
) + ', ' +
Math[darker ? 'max' : 'min'](
parseInt(decimal[2], 10) + difference, darker ? 0 : 255
) +
(alpha !== null ? ', ' + alpha : '') +
')' :
// Return hex
[
'#',
pad(Math[darker ? 'max' : 'min'](
parseInt(decimal[0], 10) + difference, darker ? 0 : 255
).toString(16), 2),
pad(Math[darker ? 'max' : 'min'](
parseInt(decimal[1], 10) + difference, darker ? 0 : 255
).toString(16), 2),
pad(Math[darker ? 'max' : 'min'](
parseInt(decimal[2], 10) + difference, darker ? 0 : 255
).toString(16), 2)
].join('');
};
var lighterColor = function(color, ratio) {
return changeColor(color, ratio, false);
};
var darkerColor = function(color, ratio) {
return changeColor(color, ratio, true);
};
// Use
var darker = darkerColor('rgba(80, 75, 52, .5)', .2);
var lighter = lighterColor('rgba(80, 75, 52, .5)', .2);
Теперь обрабатывает ввод RGB(A), а также шестнадцатеричный (3 цифры или 6).