summaryrefslogtreecommitdiff
path: root/js/lib/canvas_loader.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/lib/canvas_loader.js')
-rw-r--r--js/lib/canvas_loader.js150
1 files changed, 150 insertions, 0 deletions
diff --git a/js/lib/canvas_loader.js b/js/lib/canvas_loader.js
new file mode 100644
index 0000000..c2ed31a
--- /dev/null
+++ b/js/lib/canvas_loader.js
@@ -0,0 +1,150 @@
+var CanvasLoader = (function(){
+
+ var loader = new Loader (function(){})
+
+ function CanvasLoader (opt){
+ this.opt = defaults(opt, {
+ rotate: true,
+ })
+ this.canvas = document.createElement("canvas")
+ this.ctx = this.canvas.getContext('2d')
+ }
+ CanvasLoader.prototype.load_image = function(url, cb){
+ loader.preloadImage(url, function(img){
+ var w = this.w = img.naturalWidth
+ var h = this.h = img.naturalHeight
+ this.img = img
+ cb(img, w, h)
+ }.bind(this))
+ }
+ CanvasLoader.prototype.scale_image_data = function(opt){
+ var w, h
+ if (opt.scale) {
+ w = this.w * opt.scale
+ h = this.h * opt.scale
+ }
+ if (opt.w) {
+ w = opt.w
+ h = opt.w * this.h / this.w
+ }
+ else if (opt.h) {
+ w = opt.h * this.w / this.h
+ h = opt.h
+ }
+ this.canvas.width = w
+ this.canvas.height = h
+ this.ctx.save()
+
+ if (this.opt.rotate) {
+ this.ctx.translate(w/2, h/2)
+ this.ctx.rotate( Math.PI )
+ this.ctx.translate(-w/2, -h/2)
+ }
+
+ this.ctx.drawImage(this.img, 0, 0, w, h)
+ this.ctx.restore()
+ return this.ctx.getImageData(0, 0, w, h)
+ }
+ CanvasLoader.prototype.gray_image_data = function(opt){
+ var data = this.scale_image_data(opt)
+ var pixels = data.data
+ var len = data.width * data.height
+ var gray_data = new Uint8Array( len )
+ var invert = this.opt.invert
+
+ var gray, ii
+ for (var i = 0; i < len; i++) {
+ ii = i * 4
+ gray = (255 - (pixels[ii] + pixels[ii+1] + pixels[ii+2]) / 3 ) * (pixels[ii+3]/255)
+ gray_data[i] = (invert) ? 255 - gray : gray
+ }
+
+ return {
+ width: data.width,
+ height: data.height,
+ data: gray_data,
+ }
+ }
+ // in: imagedata [r,g,b,a] and a palette
+ // out: an array strided as [ palette offset, alpha ]
+ CanvasLoader.prototype.palette_image_data = function(opt){
+ var data = this.scale_image_data(opt)
+ var pixels = data.data
+ var len = data.width * data.height
+ var palette_data = new Uint8Array( len*2 )
+ var invert = this.opt.invert
+
+ var palette = this.paletteToNumbers(opt.palette)
+
+ var color, index, ii
+ for (var i = 0; i < len; i++) {
+ ii = i * 2
+ jj = i * 4
+ index = closest_to( palette, pixels.slice(jj, jj+3) )
+ palette_data[ii] = index
+ palette_data[ii+1] = pixels[jj+3]
+ }
+
+ return {
+ width: data.width,
+ height: data.height,
+ data: palette_data,
+ }
+ }
+
+ CanvasLoader.prototype.paletteToStrings = function (palette){
+ if (typeof palette[0] === "string") return palette
+ return palette.map(function(rgb){
+ return "rgb(" + rgb.join(",") + ")"
+ })
+ }
+ CanvasLoader.prototype.paletteToNumbers = function (palette){
+ if (typeof palette[0] !== "string") return palette
+ var colors = palette.map(function(color){
+ if (color[0] == "#") return hexToRgb(color)
+ return rgbStringToRgb(color)
+ }).filter(function(color){ return !! color }).map(function(rgb){
+ return [rgb.r, rgb.g, rgb.b]
+ })
+ return colors
+ }
+
+ function hexToRgb(hex) {
+ // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
+ var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
+ hex = hex.replace(shorthandRegex, function(m, r, g, b) {
+ return r + r + g + g + b + b;
+ });
+
+ var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+ return result ? {
+ r: parseInt(result[1], 16),
+ g: parseInt(result[2], 16),
+ b: parseInt(result[3], 16)
+ } : null;
+ }
+ function rgbStringToRgb(rgb) {
+ var nums = rgb.replace(/rgba?\(/,"").replace(/\)/,"").split(",")
+ return { r: nums[0], g: nums[1], b: nums[2] }
+ }
+ function closest_to(palette, pixel){
+ return palette.reduce(function(prev, curr, index) {
+ var d = distance(pixel, curr)
+ if (prev[0] > d) {
+ prev[0] = d
+ prev[1] = index
+ }
+ return prev
+ }, [Infinity, -1])[1]
+ }
+ function distance(u, v){
+ if (! v) return Math.Infinity
+ var r = u[0] - v[0]
+ var g = u[1] - v[1]
+ var b = u[2] - v[2]
+ return Math.sqrt(r*r+g*g+b*b)
+ }
+
+ return CanvasLoader
+
+})() \ No newline at end of file