summaryrefslogtreecommitdiff
path: root/public/assets/js/lib/ascii
diff options
context:
space:
mode:
authorJules Laplace <jules@okfoc.us>2016-11-15 17:26:44 -0500
committerJules Laplace <jules@okfoc.us>2016-11-15 17:26:44 -0500
commit9beaf2708b012b9533ca3088fbddd542a3c6c076 (patch)
tree895c29544d96685e3812a92420ea62a8537705a2 /public/assets/js/lib/ascii
parent468c23aae285e8845a16e4df527d37db9fef420b (diff)
dumping color codes to irc
Diffstat (limited to 'public/assets/js/lib/ascii')
-rw-r--r--public/assets/js/lib/ascii/color.js251
-rw-r--r--public/assets/js/lib/ascii/photo.js336
2 files changed, 587 insertions, 0 deletions
diff --git a/public/assets/js/lib/ascii/color.js b/public/assets/js/lib/ascii/color.js
new file mode 100644
index 0000000..ac90a3d
--- /dev/null
+++ b/public/assets/js/lib/ascii/color.js
@@ -0,0 +1,251 @@
+// http://www.easyrgb.com/index.php?X=MATH&H=01#text1
+
+function rgb(x,y,z){
+ r=x; g=y; b=z
+}
+function rgbref(rgb){
+ r=rgb[0]; g=rgb[1]; b=rgb[2];
+}
+function black(){ rgb(0,0,0) }
+function white(){ rgb(255,255,255) }
+function red(){ rgb(255,0,0) }
+function gray(n){ n<1&&(n*=255);rgb(n,n,n) }
+
+function rgb2xyz(rgb){
+ var var_R = ( rgb[0] / 255 ) //R from 0 to 255
+ var var_G = ( rgb[1] / 255 ) //G from 0 to 255
+ var var_B = ( rgb[2] / 255 ) //B from 0 to 255
+
+ if ( var_R > 0.04045 ) var_R = Math.pow( ( var_R + 0.055 ) / 1.055, 2.4)
+ else var_R = var_R / 12.92
+ if ( var_G > 0.04045 ) var_G = Math.pow( ( var_G + 0.055 ) / 1.055, 2.4)
+ else var_G = var_G / 12.92
+ if ( var_B > 0.04045 ) var_B = Math.pow( ( var_B + 0.055 ) / 1.055, 2.4)
+ else var_B = var_B / 12.92
+
+ var_R = var_R * 100
+ var_G = var_G * 100
+ var_B = var_B * 100
+
+ //Observer. = 2°, Illuminant = D65
+ var x = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805
+ var y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722
+ var z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505
+ return [x,y,z];
+}
+function xyz2rgb(xyz){
+ var var_X = xyz[0] / 100 //X from 0 to 95.047 (Observer = 2°, Illuminant = D65)
+ var var_Y = xyz[1] / 100 //Y from 0 to 100.000
+ var var_Z = xyz[2] / 100 //Z from 0 to 108.883
+
+ var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986
+ var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415
+ var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570
+
+ if ( var_R > 0.0031308 ) var_R = 1.055 * Math.pow( var_R, 1 / 2.4 ) - 0.055
+ else var_R = 12.92 * var_R
+ if ( var_G > 0.0031308 ) var_G = 1.055 * Math.pow( var_G, 1 / 2.4 ) - 0.055
+ else var_G = 12.92 * var_G
+ if ( var_B > 0.0031308 ) var_B = 1.055 * Math.pow( var_B, 1 / 2.4 ) - 0.055
+ else var_B = 12.92 * var_B
+
+ var r = clamp(var_R * 255, 0, 255)
+ var g = clamp(var_G * 255, 0, 255)
+ var b = clamp(var_B * 255, 0, 255)
+ return [r,g,b]
+}
+
+function xyz2hunterlab (XYZ) {
+ var X = XYZ[0]
+ var Y = XYZ[1] || 1e-6 // otherwise divide-by-zero error when converting rgb(0,0,0)
+ var Z = XYZ[2]
+ var L = 10 * sqrt( Y )
+ var a = 17.5 * ( ( ( 1.02 * X ) - Y ) / sqrt( Y ) )
+ var b = 7 * ( ( Y - ( 0.847 * Z ) ) / sqrt( Y ) )
+ return [L,a,b]
+}
+
+function hunterlab2xyz (Lab) {
+ var L = Lab[0]
+ var a = Lab[1]
+ var b = Lab[2]
+ var_Y = L / 10
+ var_X = a / 17.5 * L / 10
+ var_Z = b / 7 * L / 10
+
+ Y = Math.pow(var_Y, 2)
+ X = ( var_X + Y ) / 1.02
+ Z = -( var_Z - Y ) / 0.847
+ return [X,Y,Z]
+}
+// Daylight Illuminant (D65)
+var REF_X = 95.047
+var REF_Y = 100.000
+var REF_Z = 108.883
+
+function xyz2cielab (xyz) {
+ var var_X = xyz[0] / ref_X //ref_X = 95.047 Observer= 2°, Illuminant= D65
+ var var_Y = xyz[1] / ref_Y //ref_Y = 100.000
+ var var_Z = xyz[2] / ref_Z //ref_Z = 108.883
+
+ if ( var_X > 0.008856 ) var_X = Math.pow( var_X, 1/3 )
+ else var_X = ( 7.787 * var_X ) + ( 16 / 116 )
+ if ( var_Y > 0.008856 ) var_Y = Math.pow( var_Y, 1/3 )
+ else var_Y = ( 7.787 * var_Y ) + ( 16 / 116 )
+ if ( var_Z > 0.008856 ) var_Z = Math.pow(var_Z, 1/3 )
+ else var_Z = ( 7.787 * var_Z ) + ( 16 / 116 )
+
+ var L = ( 116 * var_Y ) - 16
+ var a = 500 * ( var_X - var_Y )
+ var b = 200 * ( var_Y - var_Z )
+
+ return [L,a,b]
+}
+
+function cielab2xyz (lab){
+ var var_Y = ( lab[0] + 16 ) / 116
+ var var_X = lab[1] / 500 + var_Y
+ var var_Z = var_Y - lab[2] / 200
+
+ if ( Math.pow(var_Y, 3) > 0.008856 ) var_Y = Math.pow(var_Y, 3)
+ else var_Y = ( var_Y - 16 / 116 ) / 7.787
+ if ( Math.pow(var_X, 3) > 0.008856 ) var_X = Math.pow(var_X, 3)
+ else var_X = ( var_X - 16 / 116 ) / 7.787
+ if ( Math.pow(var_Z, 3) > 0.008856 ) var_Z = Math.pow(var_Z, 3)
+ else var_Z = ( var_Z - 16 / 116 ) / 7.787
+
+ var x = REF_X * var_X //ref_X = 95.047 Observer= 2°, Illuminant= D65
+ var y = REF_Y * var_Y //ref_Y = 100.000
+ var z = REF_Z * var_Z //ref_Z = 108.883
+
+ return [x,y,z]
+}
+
+function rgb2hsl (RGB){
+ var R = RGB[0]
+ var G = RGB[1]
+ var B = RGB[2]
+ var var_R = ( R / 255 ) //RGB from 0 to 255
+ var var_G = ( G / 255 )
+ var var_B = ( B / 255 )
+
+ var var_Min = Math.min( var_R, var_G, var_B ) //Min. value of RGB
+ var var_Max = Math.max( var_R, var_G, var_B ) //Max. value of RGB
+ var del_Max = var_Max - var_Min //Delta RGB value
+
+ var H,S;
+ var L = ( var_Max + var_Min ) / 2
+
+ if ( del_Max == 0 ) //This is a gray, no chroma...
+ {
+ H = 0 //HSL results from 0 to 1
+ S = 0
+ }
+ else //Chromatic data...
+ {
+ if ( L < 0.5 ) S = del_Max / ( var_Max + var_Min )
+ else S = del_Max / ( 2 - var_Max - var_Min )
+
+ var del_R = ( ( ( var_Max - var_R ) / 6 ) + ( del_Max / 2 ) ) / del_Max
+ var del_G = ( ( ( var_Max - var_G ) / 6 ) + ( del_Max / 2 ) ) / del_Max
+ var del_B = ( ( ( var_Max - var_B ) / 6 ) + ( del_Max / 2 ) ) / del_Max
+
+ if ( var_R == var_Max ) H = del_B - del_G
+ else if ( var_G == var_Max ) H = ( 1 / 3 ) + del_R - del_B
+ else if ( var_B == var_Max ) H = ( 2 / 3 ) + del_G - del_R
+
+ if ( H < 0 ) H += 1
+ if ( H > 1 ) H -= 1
+ }
+ return [H,S,L]
+}
+function hsl2rgb (H, S, L) {
+ var R,G,B;
+ var var_1, var_2;
+ if ( S == 0 ) { //HSL from 0 to 1
+ R = L * 255 //RGB results from 0 to 255
+ G = L * 255
+ B = L * 255
+ }
+ else {
+ if ( L < 0.5 ) var_2 = L * ( 1 + S )
+ else var_2 = ( L + S ) - ( S * L )
+
+ var_1 = 2 * L - var_2
+
+ R = 255 * hue2rgb( var_1, var_2, H + ( 1 / 3 ) )
+ G = 255 * hue2rgb( var_1, var_2, H )
+ B = 255 * hue2rgb( var_1, var_2, H - ( 1 / 3 ) )
+ }
+ return [R,G,B]
+}
+function hue2rgb( v1, v2, vH ) {
+ if ( vH < 0 ) vH += 1
+ if ( vH > 1 ) vH -= 1
+ if ( ( 6 * vH ) < 1 ) return ( v1 + ( v2 - v1 ) * 6 * vH )
+ if ( ( 2 * vH ) < 1 ) return ( v2 )
+ if ( ( 3 * vH ) < 2 ) return ( v1 + ( v2 - v1 ) * ( ( 2 / 3 ) - vH ) * 6 )
+ return ( v1 )
+}
+
+function rgb2cmy (R,G,B){
+ if (R.length) {
+ B = R[2]
+ G = R[1]
+ R = R[0]
+ }
+ var C = 1 - ( R / 255 )
+ var M = 1 - ( G / 255 )
+ var Y = 1 - ( B / 255 )
+ return [C,M,Y]
+}
+function cmy2rgb (C,M,Y){
+ if (C.length) {
+ Y = C[2]
+ M = C[1]
+ C = C[0]
+ }
+ var R = ( 1 - C ) * 255
+ var G = ( 1 - M ) * 255
+ var B = ( 1 - Y ) * 255
+ return [R,G,B]
+}
+function cmy2cmyk (C,M,Y) {
+ if (C.length) {
+ Y = C[2]
+ M = C[1]
+ C = C[0]
+ }
+
+ var var_K = 1
+
+ if ( C < var_K ) var_K = C
+ if ( M < var_K ) var_K = M
+ if ( Y < var_K ) var_K = Y
+ if ( var_K == 1 ) { //Black
+ C = 0
+ M = 0
+ Y = 0
+ }
+ else {
+ C = ( C - var_K ) / ( 1 - var_K )
+ M = ( M - var_K ) / ( 1 - var_K )
+ Y = ( Y - var_K ) / ( 1 - var_K )
+ }
+ var K = var_K
+ return [C,M,Y,K]
+}
+function cmyk2cmy (C,M,Y,K) {
+ if (C.length) {
+ K = C[3]
+ Y = C[2]
+ M = C[1]
+ C = C[0]
+ }
+ var C = ( C * ( 1 - K ) + K )
+ var M = ( M * ( 1 - K ) + K )
+ var Y = ( Y * ( 1 - K ) + K )
+ return [C,M,Y]
+}
+
+
diff --git a/public/assets/js/lib/ascii/photo.js b/public/assets/js/lib/ascii/photo.js
new file mode 100644
index 0000000..1a1c6d6
--- /dev/null
+++ b/public/assets/js/lib/ascii/photo.js
@@ -0,0 +1,336 @@
+
+var Photo = (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]
+ ]
+ var HUES = [
+ [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],
+ null,
+ null,
+ ]
+ var GRAYS = [
+ [255,255,255],
+ [0,0,0],
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ [127,127,127],
+ [210,210,210]
+ ]
+ var REDS = [
+ [255,255,255],
+ [0,0,0],
+ null,
+ null,
+ [255,0,0],
+ [127,0,0],
+ null,
+ [252,127,0],
+ [255,255,0],
+ null,
+ null,
+ null,
+ null,
+ [255,0,255],
+ null,
+ null,
+ ]
+ var YELLOWS = [
+ [255,255,255],
+ [0,0,0],
+ null,
+ [0,147,0],
+ null,
+ null,
+ null,
+ [252,127,0],
+ [255,255,0],
+ [0,252,0],
+ null,
+ [0,255,255],
+ null,
+ null,
+ null,
+ null,
+ ]
+ var BLUES = [
+ [255,255,255],
+ [0,0,0],
+ [0,0,127],
+ null,
+ null,
+ null,
+ [156,0,156],
+ null,
+ null,
+ [0,252,0],
+ [0,147,147],
+ [0,255,255],
+ [0,0,252],
+ [255,0,255],
+ null,
+ null,
+ ]
+ var colors = COLORS, recolor_fn = null, shade_fn = null, cc_recolor_fn = null
+ var canvas = document.createElement("canvas"), ctx = canvas.getContext('2d'), pixels
+
+ function set_colors (a) {
+ colors = a
+ }
+ function set_shade_fn (fn) {
+ shade_fn = fn
+ }
+ function set_recolor_fn (fn) {
+ recolor_fn = fn
+ }
+ function set_cc_recolor_fn (fn) {
+ cc_recolor_fn = fn
+ }
+
+ function closest_to(pixel){
+ if (recolor_fn) {
+ pixel = recolor_fn(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){
+ 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)
+ }
+
+ 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]
+ if (shade_fn) {
+ shade_fn(data, pixel, j, i, w, h)
+ }
+ if (Photo.denoise) { denoise_pixel(data, w, h, i, j, pixel, Photo.denoise) }
+ row[j] = closest_to(pixel)
+ if (cc_recolor_fn) row[j] = cc_recolor_fn(row[j])
+ }
+ }
+ if (! cb) return rows
+ else cb (rows)
+ }
+ function denoise_pixel (d, w, h, x, y, pixel, exponent){
+ var rr = r, gg = g, bb = b;
+ var color = [0,0,0]
+ var total = 0.0
+ var xx, yy, x0, y0, weight, r, g, b, t
+ for (xx = -4.0; xx <= 4.0; xx += 1.0) {
+ x0 = x+xx
+ if (x0 < 0 || x0 >= w) continue
+ for (yy = -4.0; yy <= 4.0; yy += 1.0) {
+ y0 = y+yy
+ if (y0 < 0 || y0 >= h) continue
+ t = (x+xx + w*(y+yy)) * 4
+ r = d[ t ]
+ g = d[ t+1 ]
+ b = d[ t+2 ]
+ weight = 1.0 - Math.abs( 0.25 * ((rr-r)/255 + (gg-g)/255 + (bb-b)/255) )
+ weight = pow( weight, exponent )
+ color[0] += r * weight
+ color[1] += g * weight
+ color[2] += b * weight
+ total += weight
+ }
+ }
+ pixel[0] = color[0] * 255 / total
+ pixel[1] = color[1] * 255 / total
+ pixel[2] = color[2] * 255 / total
+ }
+ function getNaturalDimensions (img) {
+ if (img.naturalWidth) {
+ return { naturalWidth: img.naturalWidth, naturalHeight: img.naturalHeight }
+ }
+ if (img.videoWidth) {
+ return { naturalWidth: img.videoWidth, naturalHeight: img.videoHeight }
+ }
+ return { naturalWidth: img.width, naturalHeight: img.height }
+ }
+ function neighbor (canvas, ctx, img) {
+ var dims = getNaturalDimensions(img)
+ var scratch = document.createElement("canvas")
+ var scratchCtx = scratch.getContext('2d')
+ scratch.width = dims.naturalWidth
+ scratch.height = dims.naturalHeight
+ scratchCtx.drawImage(img, 0, 0, dims.naturalWidth, dims.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(){
+ fromCanvas(img, cb, opt)
+ }
+ if (img.src == url) { return img.onload() }
+ img.src = url
+ if (img.complete) { return img.onload() }
+ }
+ function fromCanvas (img, cb, opt) {
+ var dims = getNaturalDimensions(img)
+ 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 = (dims.naturalHeight * width / dims.naturalWidth) / 2
+ }
+ }
+ else {
+ canvas.width = dims.naturalWidth * 2
+ canvas.height = dims.naturalHeight
+ }
+ if (opt.neighbor) {
+ pixels = neighbor(canvas, ctx, img)
+ }
+ else {
+ ctx.drawImage(img,0,0,dims.naturalWidth,dims.naturalHeight,0,0,canvas.width,canvas.height)
+ pixels = ctx.getImageData(0,0,canvas.width,canvas.height)
+ }
+ fromImageData(pixels, cb)
+ }
+ function ascii (rows) {
+ var lines = rows.map(function(str){
+ var last = -1
+ return str.map(function(index){
+ if (last == index) return " "
+ last = index
+ return "\\x031," + index + " "
+ }).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-c1," + index + " " }).join("")
+ }).join("\n"))
+ }, width)
+ }
+ function mirc (rows) {
+ return rows.map(function(str){
+ var last = -1
+ return str.map(function(index){
+ if (last == index) {
+ return " "
+ }
+ else {
+ last = index
+ return "\u00031," + index + " "
+ }
+ }).join("")
+ }).join("\u0003\n")
+ }
+
+ var Photo = {
+ colors: COLORS,
+ hues: HUES,
+ grays: GRAYS,
+ reds: REDS,
+ yellows: YELLOWS,
+ blues: BLUES,
+ set_shade_fn: set_shade_fn,
+ set_recolor_fn: set_recolor_fn,
+ set_cc_recolor_fn: set_cc_recolor_fn,
+ set_colors: set_colors,
+ closest_to: closest_to,
+ distance: distance,
+ fromUrl: fromUrl,
+ fromCanvas: fromCanvas,
+ fromImageData: fromImageData,
+ stringFromUrl: stringFromUrl,
+ asciiFromUrl: asciiFromUrl,
+ ascii: ascii,
+ mirc: mirc,
+ neighbor: neighbor,
+ denoise: 0,
+ }
+ return Photo
+
+})()
+
+