Вы можете просто сделать линейный inpterpolation между двумя цветами, «черным» цветом, который соответствует сере нулевого значения и «белому» цвета, который соответствует серому значению 255.
Эффекта вы описать будет использовать вашу пастель как «черный» и белый как «белый». Цветовые интерполяции в пространстве RGB сложны, когда задействованы разные оттенки, но в вашем случае, когда два цвета имеют одинаковые или похожие оттенки, проблем не должно быть. (Ваш исходный код, чтобы получить красивый пастельный цвет, вероятно, использует тот же механизм, интерполируя на полпути между белым и случайным цветом.)
Вот пример, который превращает данные изображения в оттенках серого в пастельную цветовую схему на основе красного значения данные. (Жако имеют три одинаковых цветовых компонентов, но никаких усилий не делается для того, чтобы.)
function pastel(idata, black, white) {
var data = idata.data;
var n = 0;
for (var y = 0; y < idata.height; y++) {
for (var x = 0; x < idata.width; x++) {
var grey = data[n]/255.0;
var yerg = 1.0 - grey;
data[n++] = (yerg * black.r + grey * white.r) | 0;
data[n++] = (yerg * black.g + grey * white.g) | 0;
data[n++] = (yerg * black.b + grey * white.b) | 0;
n++;
}
}
}
Редактировать: Вот полный веб-страницы для йор копирования и вставки удовольствия. У вас должен быть файл изображения "pic.png"
в том же каталоге. Цвета - это объекты Javascript с полями r
, g
и b
.
Данные изображения поступают с холста, на который нарисовано изображение. Данные изображения содержат пиксели в формате rgba
; его можно манипулировать, а затем снова помещать на холст. (В цикле Лишний n++
пропускает значение альфа и оставляет его без изменений.)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Colour Interpolation</title>
<script type="text/javascript">
function pastel(idata, black, white) {
var data = idata.data;
var n = 0;
for (var y = 0; y < idata.height; y++) {
for (var x = 0; x < idata.width; x++) {
var grey = data[n]/255.0;
var yerg = 1.0 - grey;
data[n++] = (yerg * black.r + grey * white.r) | 0;
data[n++] = (yerg * black.g + grey * white.g) | 0;
data[n++] = (yerg * black.b + grey * white.b) | 0;
n++;
}
}
}
window.onload = function() {
var cv = document.getElementById("map");
var cx = cv.getContext("2d");
var img = document.createElement('img');
img.src = "pic.png";
img.onload = function(e) {
var img = this;
img.width = img.naturalWidth;
img.height = img.naturalHeight;
cv.width = img.width ;
cv.height = img.height;
cx.drawImage(img, 0, 0);
var idata = cx.getImageData(0, 0, img.width, img.height);
pastel(idata,
{r: 102, g: 51, b: 0},
{r: 255, g: 255, b: 204});
cx.putImageData(idata, 0, 0);
};
}
</script>
</head>
<body>
<canvas id="map" width="96" height="96">Kann nix.</canvas>
</body>
</html>
Просто умножьте значения RGB с серым значением и разделить на максимум (вероятно, 255)? –
Поиск «яркости» здесь, в разделе «Переполнение стека», вы должны начать. – m69
Спасибо @SamiKuhmonen, это прекрасно работает! – user1658080