var MircColor = (function(){ var COLORS = [ [255,255,255], [0,0,0], [0,0,127], [0,147,0], [255,0,0], [127,0,0], [156,0,156], [252,127,0], [255,255,0], [0,252,0], [0,147,147], [0,255,255], [0,0,252], [255,0,255], [127,127,127], [210,210,210] ] function closest_to(pixel){ return COLORS.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){ 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) } function fromImageData (pixels, cb){ var rows = [], pixel = new Array (4), data = pixels.data, t for (var i = 0, h = pixels.height; i < h; i++) { var row = [] rows.push(row) for (var j = 0, w = pixels.width; j < w; j++) { t = (i*w+j)*4 pixel[0] = data[t] pixel[1] = data[t+1] pixel[2] = data[t+2] pixel[3] = data[t+3] row[j] = closest_to(pixel) } } if (! cb) return rows else cb (rows) } function neighbor (canvas, ctx, img) { var scratch = document.createElement("canvas") var scratchCtx = scratch.getContext('2d') scratch.width = img.naturalWidth scratch.height = img.naturalHeight scratchCtx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight) var srcImageData = scratchCtx.getImageData(0,0,scratch.width,scratch.height) var destImageData = ctx.createImageData(canvas.width,canvas.height) var src = srcImageData.data, dest = destImageData.data var dt, dw = destImageData.width, dh = destImageData.height var st, sw = srcImageData.width, sh = srcImageData.height for (var i = 0; i < dh; i++) { for (var j = 0; j < dw; j++) { var y = i * sh/dh var x = j * sw/dw dt = ((i*dw) + j) * 4 st = Math.floor( Math.floor(y)*sw + x ) * 4 dest[dt] = src[st] dest[dt+1] = src[st+1] dest[dt+2] = src[st+2] dest[dt+3] = src[st+3] } } return destImageData } var img = new Image () function fromUrl (url, cb, opt) { img.onload = function(){ var canvas = document.createElement("canvas"), ctx = canvas.getContext('2d'), pixels if (opt.width) { canvas.width = opt.width if (opt.height) { canvas.height = opt.height } else if (opt.ratio) { canvas.height = opt.width / opt.ratio } else { canvas.height = (img.naturalHeight * width / img.naturalWidth) / 2 } } else { canvas.width = img.naturalWidth * 2 canvas.height = img.naturalHeight } if (opt.neighbor) { pixels = neighbor(canvas, ctx, img) } else { ctx.drawImage(img,0,0,img.naturalWidth,img.naturalHeight,0,0,canvas.width,canvas.height) pixels = ctx.getImageData(0,0,canvas.width,canvas.height) } fromImageData(pixels, cb) } if (img.src == url) { return img.onload() } img.src = url if (img.complete) { return img.onload() } } function ascii (rows) { var lines = rows.map(function(str){ return str.map(function(index){ return "\\x03" + index + "," + index + "x\\x03" }).join("") }).join("\\n") var txt = '/exec -out printf "' + lines + '"\n' return txt } function asciiFromUrl (url, cb, opt) { fromUrl(url, function(rows){ cb(ascii(rows), rows) }, width) } function stringFromUrl (url, cb, opt) { fromUrl(url, function(rows){ cb(rows.map(function(str){ return str.map(function(index){ return "\C-c" + index + "," + index + "x\C-c" }).join("") }).join("\n")) }, width) } return { colors: COLORS, closest_to: closest_to, distance: distance, fromUrl: fromUrl, fromImageData: fromImageData, stringFromUrl: stringFromUrl, asciiFromUrl: asciiFromUrl, ascii: ascii, neighbor: neighbor, } })()