Skip to content

Instantly share code, notes, and snippets.

@jonathantneal
Created March 19, 2012 01:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonathantneal/2088793 to your computer and use it in GitHub Desktop.
Save jonathantneal/2088793 to your computer and use it in GitHub Desktop.
Canvas Prototype
// Canvas Prototype (because prototyping has always proven to be such a great idea...)
if (HTMLCanvasElement) {
function RGBToHSL(r, g, b) {
var
min = Math.min(r, g, b),
max = Math.max(r, g, b),
diff = max - min,
h = 0, s = 0, l = (min + max) / 2;
if (diff != 0) {
s = l < 0.5 ? diff / (max + min) : diff / (2 - max - min);
h = (r == max ? (g - b) / diff : g == max ? 2 + (b - r) / diff : 4 + (r - g) / diff) * 60;
}
return [h, s, l];
}
function HSLToRGB(h, s, l) {
if (s == 0) {
return [l, l, l];
}
var temp2 = l < 0.5 ? l * (1 + s) : l + s - l * s;
var temp1 = 2 * l - temp2;
h /= 360;
var
rtemp = (h + 1 / 3) % 1,
gtemp = h,
btemp = (h + 2 / 3) % 1,
rgb = [rtemp, gtemp, btemp],
i = 0;
for (; i < 3; ++i) {
rgb[i] = rgb[i] < 1 / 6 ? temp1 + (temp2 - temp1) * 6 * rgb[i] : rgb[i] < 1 / 2 ? temp2 : rgb[i] < 2 / 3 ? temp1 + (temp2 - temp1) * 6 * (2 / 3 - rgb[i]) : temp1;
}
return rgb;
}
HTMLCanvasElement.prototype.getImageData = function (x, y, width, height) {
return this.getContext('2d').getImageData(parseFloat(x) || 0, parseFloat(y) || 0, width != null ? parseFloat(width) : this.width, height != null ? parseFloat(height) : this.height);
};
HTMLCanvasElement.prototype.putImageData = function (imageData, x, y) {
return this.getContext('2d').putImageData(imageData, parseFloat(x) || 0, parseFloat(y) || 0) && this;
};
HTMLCanvasElement.prototype.editImageData = function (callback, x, y, width, height) {
var canvas = this;
if (typeof callback == 'function') {
var imageData = canvas.getImageData(x, y, width, height);
callback.call(canvas, imageData);
canvas.putImageData(imageData, x, y);
}
return canvas;
};
HTMLCanvasElement.prototype.trim = function () {
var
canvas = this,
imageData = canvas.getImageData(),
width = imageData.width,
height = imageData.height,
pixels = width * height,
canvasPixelArray = imageData.data,
top = height,
right = 0,
bottom = 0,
left = width,
i = 1,
row;
for (; i < pixels; ++i) {
if (canvasPixelArray[i * 4 - 1] > 0) {
row = Math.floor(i / width);
top = Math.min(top, row);
right = Math.max(right, (i % width) + 1);
bottom = Math.max(bottom, row + 1);
left = Math.min(left, i % width);
}
}
canvas.width = right - left;
canvas.height = bottom - top;
canvas.putImageData(imageData, 0 - left, 0 - top);
return canvas;
};
HTMLCanvasElement.prototype.whiteTransparency = function(feather) {
feather = parseFloat(feather) || 0;
return this.editImageData(function (imageData) {
var
canvasPixelArray = imageData.data,
pixels = imageData.width * imageData.height,
whiteFeather = 255 - feather,
i = 1,
minimumRGB;
for (; i < pixels; ++i) {
minimumRGB = Math.min(canvasPixelArray[i * 4 - 4], canvasPixelArray[i * 4 - 3], canvasPixelArray[i * 4 - 2]);
if (minimumRGB >= whiteFeather) {
canvasPixelArray[i * 4 - 1] = 0 + (255 - minimumRGB);
}
}
});
};
HTMLCanvasElement.prototype.brightness = function (value) {
value = parseFloat(value) || 0;
return this.editImageData(function (imageData) {
var canvasPixelArray = imageData.data;
var pixels = imageData.width * imageData.height;
var i = 1;
for (; i < pixels; ++i) {
canvasPixelArray[i * 4 - 4] += value;
canvasPixelArray[i * 4 - 3] += value;
canvasPixelArray[i * 4 - 2] += value;
}
});
};
HTMLCanvasElement.prototype.contrast = function (value) {
value = (parseFloat(value) || 0) + 1;
return this.editImageData(function (imageData) {
var
canvasPixelArray = imageData.data,
pixels = imageData.width * imageData.height,
i = 1,
r, g, b;
for (; i < pixels; ++i) {
r = i * 4 - 4;
g = i * 4 - 3;
b = i * 4 - 2;
canvasPixelArray[r] = ((((canvasPixelArray[r] / 255) - 0.5) * value) + 0.5) * 255;
canvasPixelArray[g] = ((((canvasPixelArray[g] / 255) - 0.5) * value) + 0.5) * 255;
canvasPixelArray[b] = ((((canvasPixelArray[b] / 255) - 0.5) * value) + 0.5) * 255;
}
});
};
HTMLCanvasElement.prototype.desaturate = function () {
return this.editImageData(function (imageData) {
var
canvasPixelArray = imageData.data,
pixels = imageData.width * imageData.height,
i = 1,
r, g, b;
for (; i < pixels; ++i) {
r = i * 4 - 4;
g = i * 4 - 3;
b = i * 4 - 2;
grayscale = canvasPixelArray[r] * 0.3 + canvasPixelArray[g] * 0.59 + canvasPixelArray[b] * 0.11;
canvasPixelArray[r] = grayscale;
canvasPixelArray[g] = grayscale;
canvasPixelArray[b] = grayscale;
}
});
};
HTMLCanvasElement.prototype.rotation = function (value) {
value = parseFloat(value) || 0;
var
canvas = this,
canvasClone = document.createElement('canvas'),
context = canvas.getContext('2d'),
width = context.canvas.width,
height = context.canvas.height;
canvasClone.width = width;
canvasClone.height = height;
canvasClone.getContext('2d').putImageData(context.getImageData(0, 0, width, height), 0, 0);
canvas.width = width;
canvas.height = height;
context.translate(width / 2, canvas.height / 2);
context.rotate(Math.PI * (value / 180));
context.translate(-width / 2,- height / 2);
context.drawImage(canvasClone, 0, 0);
return canvas;
};
HTMLCanvasElement.prototype.saturation = function (value) {
value = parseFloat(value) || 0;
return this.editImageData(function (imageData) {
var
canvasPixelArray = imageData.data,
pixels = imageData.width * imageData.height,
i = 1,
r, g, b, hsl, rgb;
for (; i < pixels; ++i) {
r = i * 4 - 4;
g = i * 4 - 3;
b = i * 4 - 2;
hsl = RGBToHSL(canvasPixelArray[r] / 255, canvasPixelArray[g] / 255, canvasPixelArray[b] / 255);
hsl[1] = Math.max(0, hsl[1] + value);
rgb = HSLToRGB(hsl[0], hsl[1], hsl[2]);
canvasPixelArray[r] = rgb[0] * 255;
canvasPixelArray[g] = rgb[1] * 255;
canvasPixelArray[b] = rgb[2] * 255;
}
});
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment