Created
September 27, 2017 19:23
-
-
Save matsadler/bf8c1b78295955fe56dc603237da0dcf to your computer and use it in GitHub Desktop.
Javascript to apply a colour tint to an image
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Test</title> | |
<script src="tint.js"></script> | |
<script> | |
document.addEventListener("DOMContentLoaded", function () { | |
document.querySelectorAll("img").forEach(function (img) { | |
img.addEventListener("load", function () { | |
tint(img); | |
}); | |
}) | |
}); | |
</script> | |
</head> | |
<body> | |
<img src="test.jpg"> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// img should be an img element (ensure the image has loaded first) | |
// | |
// hue sets the colour, and is a float in the range 0-1. | |
// | |
// saturation is how much colour, and is a float in the range 0-1. | |
// Default: 0.6 | |
// | |
// white is the white point, a lower value will move white towards grey, | |
// allowing more colour into the image, but making it dimmer. Default: 1 | |
// | |
// black is the black point, a higher value will move black towards grey, | |
// allowing more colour into the image, but making it appear washed out. | |
// Default: 0 | |
// | |
function tint(img, hue, saturation, white, black) { | |
hue = hue || 0.6; | |
saturation = saturation || 0.6; | |
black = black || 0; | |
white = white || 1; | |
newPixels = hsvFilter(getPixels(img), function(pixel) { | |
pixel[0] = hue; | |
pixel[1] = saturation; | |
pixel[2] = ((white - black) / 1) * pixel[2] + black; | |
return pixel; | |
}); | |
var canvas = document.createElement("canvas"); | |
canvas.width = img.width; | |
canvas.height = img.height; | |
putPixels(canvas.getContext("2d"), newPixels, img.width, img.height); | |
img.src = canvas.toDataURL(); | |
} | |
function getPixels(img) { | |
var canvas = document.createElement("canvas"), | |
pixels = [], | |
rgbPixel, | |
ctx, | |
data, | |
i; | |
canvas.width = img.width; | |
canvas.height = img.height; | |
ctx = canvas.getContext("2d"); | |
ctx.drawImage(img, 0, 0, img.width, img.height); | |
data = ctx.getImageData(0, 0, canvas.width, canvas.height).data; | |
for (i = 0; i < data.length; i += 4) { | |
rgbPixel = []; | |
rgbPixel[0] = data[i]; | |
rgbPixel[1] = data[i + 1]; | |
rgbPixel[2] = data[i + 2]; | |
pixels.push(rgbPixel); | |
} | |
return pixels; | |
} | |
function hsvFilter(pixels, filter) { | |
var result = [], | |
i; | |
for (i = 0; i < pixels.length; i += 1) { | |
result[i] = hsvToRgb(filter(rgbToHsv(pixels[i]))); | |
} | |
return result; | |
} | |
function putPixels(ctx, rgb, width, height) { | |
var imageData = ctx.createImageData(width, height), | |
i = 0, | |
j = 0; | |
for (i = 0; i < rgb.length; i += 1) { | |
imageData.data[j] = rgb[i][0]; | |
imageData.data[j + 1] = rgb[i][1]; | |
imageData.data[j + 2] = rgb[i][2]; | |
imageData.data[j + 3] = 255; | |
j += 4; | |
} | |
ctx.putImageData(imageData, 0, 0); | |
} | |
// adapted from from http://www.easyrgb.com/index.php?X=MATH | |
function rgbToHsv(rgb, buffer) { | |
buffer = buffer || []; | |
var r = rgb[0] / 255, | |
g = rgb[1] / 255, | |
b = rgb[2] / 255, | |
min = Math.min(r, g, b), | |
max = Math.max(r, g, b), | |
delta = max - min, | |
h = 0, | |
s = 0, | |
v = max, | |
delta_r, | |
delta_g, | |
delta_b; | |
if (delta !== 0) { | |
s = delta / max; | |
delta_r = (((max - r) / 6) + (delta / 2)) / delta; | |
delta_g = (((max - g) / 6) + (delta / 2)) / delta; | |
delta_b = (((max - b) / 6) + (delta / 2)) / delta; | |
if (r === max) { | |
h = delta_b - delta_g; | |
} else if (g === max) { | |
h = (1 / 3) + delta_r - delta_b; | |
} else if (b === max) { | |
h = (2 / 3) + delta_g - delta_r; | |
} | |
if (h < 0) { | |
h += 1; | |
} | |
if (h > 1) { | |
h -= 1; | |
} | |
} | |
buffer[0] = h; | |
buffer[1] = s; | |
buffer[2] = v; | |
return buffer; | |
} | |
function hsvToRgb(hsv, buffer) { | |
buffer = buffer || []; | |
var h = hsv[0], | |
s = hsv[1], | |
v = hsv[2], | |
i, | |
a, | |
b, | |
c; | |
if (s === 0) { | |
buffer[0] = v; | |
buffer[1] = v; | |
buffer[2] = v; | |
} else { | |
if (h === 1) { | |
h = 0; | |
} else { | |
h *= 6; | |
} | |
i = Math.floor(h); | |
a = v * (1 - s); | |
b = v * (1 - s * (h - i)); | |
c = v * (1 - s * (1 - (h - i))); | |
if (i === 0) { | |
buffer[0] = v; | |
buffer[1] = c; | |
buffer[2] = a; | |
} else if (i === 1) { | |
buffer[0] = b; | |
buffer[1] = v; | |
buffer[2] = a; | |
} else if (i === 2) { | |
buffer[0] = a; | |
buffer[1] = v; | |
buffer[2] = c; | |
} else if (i === 3) { | |
buffer[0] = a; | |
buffer[1] = b; | |
buffer[2] = v; | |
} else if (i === 4) { | |
buffer[0] = c; | |
buffer[1] = a; | |
buffer[2] = v; | |
} else { | |
buffer[0] = v; | |
buffer[1] = a; | |
buffer[2] = b; | |
} | |
} | |
buffer[0] *= 255; | |
buffer[1] *= 255; | |
buffer[2] *= 255; | |
return buffer; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment