pixelplanet/public/convert2.html
2020-01-02 17:58:06 +01:00

42 lines
12 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PixelPlace.fun - Image Converter</title>
<link rel="icon" href="/favicon.ico" type="image/x-icon"/>
<script src="bundle.js"></script>
<style>
#paletta {
width: 200px;
image-rendering: pixelated;
image-rendering: -moz-crisp-edges;
margin-right: 50px;
}
</style>
<script>
function processImage(){for(var t=document.getElementsByTagName("canvas");t[0];)t[0].parentNode.removeChild(t[0]);var i=document.getElementById("img");console.time("quant"),q.dithKern=document.getElementById("dithKern").value,q.sample(i);var e=q.palette(),r=q.reduce(i);console.timeEnd("quant"),putPixels(r,i.naturalWidth,i.naturalHeight),putPixels(e,8,8,"paletta")}function putPixels(t,i,e,r){var s=document.createElement("canvas");r&&s.setAttribute("id",r),s.width=i,s.height=e;var n=s.getContext("2d"),a=n.createImageData(s.width,s.height);a.data.set(t),n.putImageData(a,0,0),document.body.appendChild(s)}(function(){function t(t){if(t=t||{},this.method=t.method||2,this.colors=t.colors||256,this.initColors=t.initColors||4096,this.initDist=t.initDist||.01,this.distIncr=t.distIncr||.005,this.hueGroups=t.hueGroups||10,this.satGroups=t.satGroups||10,this.lumGroups=t.lumGroups||10,this.minHueCols=t.minHueCols||0,this.hueStats=this.minHueCols?new i(this.hueGroups,this.minHueCols):null,this.boxSize=t.boxSize||[64,64],this.boxPxls=t.boxPxls||2,this.palLocked=!1,this.dithKern=t.dithKern||null,this.dithSerp=t.dithSerp||!1,this.dithDelta=t.dithDelta||0,this.histogram={},this.idxrgb=t.palette?t.palette.slice(0):[],this.idxi32=[],this.i32idx={},this.i32rgb={},this.useCache=!1!==t.useCache,this.cacheFreq=t.cacheFreq||10,this.reIndex=t.reIndex||0==this.idxrgb.length,this.colorDist="manhattan"==t.colorDist?function(t,i){var e=Math.abs(i[0]-t[0]),r=Math.abs(i[1]-t[1]),s=Math.abs(i[2]-t[2]);return(o*e+u*r+l*s)/d}:function(t,i){var e=i[0]-t[0],r=i[1]-t[1],s=i[2]-t[2];return Math.sqrt(o*e*e+u*r*r+l*s*s)/c},this.idxrgb.length>0){var e=this;this.idxrgb.forEach(function(t,i){var r=(255<<24|t[2]<<16|t[1]<<8|t[0])>>>0;e.idxi32[i]=r,e.i32idx[r]=i,e.i32rgb[r]=t})}}function i(t,i){this.numGroups=t,this.minCols=i,this.stats={};for(var e=-1;e<t;e++)this.stats[e]={num:0,cols:[]};this.groupsFull=0}function e(t,i,e){var r,s,n,a,h;if(t/=255,i/=255,e/=255,(r=Math.max(t,i,e))==(s=Math.min(t,i,e)))n=a=0;else{switch(h=r-s,a=(r+s)/2>.5?h/(2-r-s):h/(r+s),r){case t:n=(i-e)/h+(i<e?6:0);break;case i:n=(e-t)/h+2;break;case e:n=(t-i)/h+4}n/=6}return{h:n,s:a,l:function(t,i,e){return Math.sqrt(o*t*t+u*i*i+l*e*e)}(t,i,e)}}function r(t,i){var e=1/i,r=e/2;if(t>=1-r||t<=r)return 0;for(var s=1;s<i;s++){var n=s*e;if(t>=n-r&&t<=n+r)return s}}function s(t){return t}function n(t){return t}function a(t){return Object.prototype.toString.call(t).slice(8,-1)}function h(t,i){var e,r,s,n,h,o;switch(a(t)){case"HTMLImageElement":(e=document.createElement("canvas")).width=t.naturalWidth,e.height=t.naturalHeight,(r=e.getContext("2d")).drawImage(t,0,0);case"Canvas":case"HTMLCanvasElement":e=e||t,r=r||e.getContext("2d");case"CanvasRenderingContext2D":r=r||t,e=e||r.canvas,s=r.getImageData(0,0,e.width,e.height);case"ImageData":i=(s=s||t).width,n="CanvasPixelArray"==a(s.data)?new Uint8Array(s.data):s.data;case"Array":case"CanvasPixelArray":n=n||new Uint8Array(t);case"Uint8Array":case"Uint8ClampedArray":n=n||t,h=new Uint32Array(n.buffer);case"Uint32Array":h=h||t,n=n||new Uint8Array(h.buffer),i=i||h.length,o=h.length/i}return{can:e,ctx:r,imgd:s,buf8:n,buf32:h,width:i,height:o}}t.prototype.sample=function(t,i){if(this.palLocked)throw"Cannot sample additional images, palette already assembled.";var e=h(t,i);switch(this.method){case 1:this.colorStats1D(e.buf32);break;case 2:this.colorStats2D(e.buf32,e.width)}},t.prototype.reduce=function(t,i,e,r){if(this.palLocked||this.buildPal(),e=e||this.dithKern,r=void 0!==r?r:this.dithSerp,i=i||1,e)a=this.dither(t,e,r);else for(var s=h(t).buf32,n=s.length,a=new Uint32Array(n),o=0;o<n;o++)l=s[o],a[o]=this.nearestColor(l);if(1==i)return new Uint8Array(a.buffer);if(2==i){var u=[];for(n=a.length,o=0;o<n;o++){var l=a[o];u[o]=this.i32idx[l]}return u}},t.prototype.dither=function(t,i,e){var r={FloydSteinberg:[[7/16,1,0],[3/16,-1,1],[5/16,0,1],[1/16,1,1]],FalseFloydSteinberg:[[3/8,1,0],[3/8,0,1],[.25,1,1]],Stucki:[[8/42,1,0],[4/42,2,0],[2/42,-2,1],[4/42,-1,1],[8/42,0,1],[4/42,1,1],[2/42,2,1],[1/42,-2,2],[2/42,-1,2],[4/42,0,2],[2/42,1,2],[1/42,2,2]],Atkinson:[[1/8,1,0],[1/8,2,0],[1/8,-1,1],[1/8,0,1],[1/8,1,1],[1/8,0,2]],Jarvis:[[7/48,1,0],[5/48,2,0],[3/48,-2,1],[5/48,-1,1],[7/48,0,1],[5/48,1,1],[3/48,2,1],[1/48,-2,2],[3/48,-1,2],[5/48,0,2],[3/48,1,2],[1/48,2,2]],Burkes:[[.25,1,0],[.125,2,0],[2/32,-2,1],[.125,-1,1],[.25,0,1],[.125,1,1],[2/32,2,1]],Sierra:[[5/32,1,0],[3/32,2,0],[2/32,-2,1],[.125,-1,1],[5/32,0,1],[.125,1,1],[2/32,2,1],[2/32,-1,2],[3/32,0,2],[2/32,1,2]],TwoSierra:[[.25,1,0],[3/16,2,0],[1/16,-2,1],[.125,-1,1],[3/16,0,1],[.125,1,1],[1/16,2,1]],SierraLite:[[.5,1,0],[.25,-1,1],[.25,0,1]]};if(!i||!r[i])throw"Unknown dithering kernel: "+i;for(var s=r[i],n=h(t),a=n.buf32,o=n.width,u=n.height,l=(a.length,e?-1:1),c=0;c<u;c++){e&&(l*=-1);for(var d=c*o,f=1==l?0:o-1,g=1==l?o:0;f!==g;f+=l){var p=d+f,m=a[p],x=255&m,v=(65280&m)>>8,b=(16711680&m)>>16,y=this.nearestColor(m),w=255&y,C=(65280&y)>>8,S=(16711680&y)>>16;if(a[p]=255<<24|S<<16|C<<8|w,!(this.dithDelta&&this.colorDist([x,v,b],[w,C,S])<this.dithDelta))for(var I=x-w,D=v-C,k=b-S,A=1==l?0:s.length-1,E=1==l?s.length:0;A!==E;A+=l){var M=s[A][1]*l,P=s[A][2],q=P*o;if(M+f>=0&&M+f<o&&P+c>=0&&P+c<u){var F=s[A][0],G=p+(q+M),U=255&a[G],H=(65280&a[G])>>8,L=(16711680&a[G])>>16,j=Math.max(0,Math.min(255,U+I*F)),B=Math.max(0,Math.min(255,H+D*F)),K=Math.max(0,Math.min(255,L+k*F));a[G]=255<<24|K<<16|B<<8|j}}}}return a},t.prototype.buildPal=function(t){if(!(this.palLocked||this.idxrgb.length>0&&this.idxrgb.length<=this.colors)){var i=this.histogram,e=function(t,i){var e=[];for(var r in t)e.push(r);return f.call(e,function(i,e){return t[e]-t[i]})}(i);if(0==e.length)throw"Nothing has been sampled, palette cannot be built.";switch(this.method){case 1:for(var r=this.initColors,s=i[e[r-1]],n=e.slice(0,r),a=r,h=e.length;a<h&&i[e[a]]==s;)n.push(e[a++]);this.hueStats&&this.hueStats.inject(n);break;case 2:n=e}n=n.map(function(t){return+t}),this.reducePal(n),!t&&this.reIndex&&this.sortPal(),this.useCache&&this.cacheHistogram(n),this.palLocked=!0}},t.prototype.palette=function(t,i){return this.buildPal(i),t?this.idxrgb:new Uint8Array(new Uint32Array(this.idxi32).buffer)},t.prototype.prunePal=function(t){for(var i,e=0;e<this.idxrgb.length;e++)t[e]||(i=this.idxi32[e],this.idxrgb[e]=null,this.idxi32[e]=null,delete this.i32idx[i]);if(this.reIndex){for(var r=[],s=[],n={},a=(e=0,0);e<this.idxrgb.length;e++)this.idxrgb[e]&&(i=this.idxi32[e],r[a]=this.idxrgb[e],n[i]=a,s[a]=i,a++);this.idxrgb=r,this.idxi32=s,this.i32idx=n}},t.prototype.reducePal=function(t){if(this.idxrgb.length>this.colors){for(var i,e=t.length,r={},s=0,n=!1,a=0;a<e;a++)s!=this.colors||n||(this.prunePal(r),n=!0),i=this.nearestIndex(t[a]),s<this.colors&&!r[i]&&(r[i]=!0,s++);n||(this.prunePal(r),n=!0)}else{var h=t.map(function(t){return[255&t,(65280&t)>>8,(16711680&t)>>16]}),o=e=h.length,u=this.initDist;if(o>this.colors){for(;o>this.colors;){var l=[];for(a=0;a<e;a++){var c=h[a];if(t[a],c)for(var d=a+1;d<e;d++){var g=h[d],p=t[d];if(g){var m=this.colorDist(c,g);m<u&&(l.push([d,g,p,m]),delete h[d],o--)}}}u+=o>3*this.colors?this.initDist:this.distIncr}if(o<this.colors){f.call(l,function(t,i){return i[3]-t[3]});for(var x=0;o<this.colors;)h[l[x][0]]=l[x][1],o++,x++}}for(e=h.length,a=0;a<e;a++)h[a]&&(this.idxrgb.push(h[a]),this.idxi32.push(t[a]),this.i32idx[t[a]]=this.idxi32.length-1,this.i32rgb[t[a]]=h[a])}},t.prototype.colorStats1D=function(t){for(var i,e=this.histogram,r=t.length,s=0;s<r;s++)(4278190080&(i=t[s]))>>24!=0&&(this.hueStats&&this.hueStats.check(i),i in e?e[i]++:e[i]=1)},t.prototype.colorStats2D=function(t,i){var e=this.boxSize[0],r=this.boxSize[1],s=e*r,n=function(t,i,e,r){for(var s=t%e,n=i%r,a=t-s,h=i-n,o=[],u=0;u<i;u+=r)for(var l=0;l<t;l+=e)o.push({x:l,y:u,w:l==a?s:e,h:u==h?n:r});return o}(i,t.length/i,e,r),a=this.histogram,h=this;n.forEach(function(e){var r,n=Math.max(Math.round(e.w*e.h/s)*h.boxPxls,2),o={};!function(t,i,e){var r=t,s=r.y*i+r.x,n=(r.y+r.h-1)*i+(r.x+r.w-1),a=0,h=i-r.w+1,o=s;do{e.call(this,o),o+=++a%r.w==0?h:1}while(o<=n)}(e,i,function(i){(4278190080&(r=t[i]))>>24!=0&&(h.hueStats&&h.hueStats.check(r),r in a?a[r]++:r in o?++o[r]>=n&&(a[r]=o[r]):o[r]=1)})}),this.hueStats&&this.hueStats.inject(a)},t.prototype.sortPal=function(){var t=this;this.idxi32.sort(function(i,a){var h=t.i32idx[i],o=t.i32idx[a],u=t.idxrgb[h],l=t.idxrgb[o],c=e(u[0],u[1],u[2]),d=e(l[0],l[1],l[2]),f=u[0]==u[1]&&u[1]==u[2]?-1:r(c.h,t.hueGroups),g=(l[0]==l[1]&&l[1]==l[2]?-1:r(d.h,t.hueGroups))-f;if(g)return-g;var p=n(+d.l.toFixed(2))-n(+c.l.toFixed(2));if(p)return-p;var m=s(+d.s.toFixed(2))-s(+c.s.toFixed(2));return m?-m:void 0}),this.idxi32.forEach(function(i,e){t.idxrgb[e]=t.i32rgb[i],t.i32idx[i]=e})},t.prototype.nearestColor=function(t){var i=this.nearestIndex(t);return null===i?0:this.idxi32[i]},t.prototype.nearestIndex=function(t){if((4278190080&t)>>24==0)return null;if(this.useCache&&""+t in this.i32idx)return this.i32idx[t];for(var i,e=1e3,r=[255&t,(65280&t)>>8,(16711680&t)>>16],s=this.idxrgb.length,n=0;n<s;n++)if(this.idxrgb[n]){var a=this.colorDist(r,this.idxrgb[n]);a<e&&(e=a,i=n)}return i},t.prototype.cacheHistogram=function(t){for(var i=0,e=t[i];i<t.length&&this.histogram[e]>=this.cacheFreq;e=t[i++])this.i32idx[e]=this.nearestIndex(e)},i.prototype.check=function(t){this.groupsFull==this.numGroups+1&&(this.check=function(){});var i=255&t,s=(65280&t)>>8,n=(16711680&t)>>16,a=i==s&&s==n?-1:r(e(i,s,n).h,this.numGroups),h=this.stats[a],o=this.minCols;h.num++,h.num>o||(h.num==o&&this.groupsFull++,h.num<=o&&this.stats[a].cols.push(t))},i.prototype.inject=function(t){for(var i=-1;i<this.numGroups;i++)if(this.stats[i].num<=this.minCols)switch(a(t)){case"Array":this.stats[i].cols.forEach(function(i){-1==t.indexOf(i)&&t.push(i)});break;case"Object":this.stats[i].cols.forEach(function(i){t[i]?t[i]++:t[i]=1})}};var o=.2126,u=.7152,l=.0722,c=Math.sqrt(255*o*255+255*u*255+255*l*255),d=255*o+255*u+255*l,f=function(){var t="abcdefghijklmnopqrstuvwxyz";return"xyzvwtursopqmnklhijfgdeabc"==t.split("").sort(function(i,e){return~~(t.indexOf(e)/2.3)-~~(t.indexOf(i)/2.3)}).join("")}()?Array.prototype.sort:function(t){var i=a(this[0]);if("Number"==i||"String"==i){for(var e,r={},s=this.length,n=0;n<s;n++)e=this[n],r[e]||0===r[e]||(r[e]=n);return this.sort(function(i,e){return t(i,e)||r[i]-r[e]})}return r=this.map(function(t){return t}),this.sort(function(i,e){return t(i,e)||r.indexOf(i)-r.indexOf(e)})};this.RgbQuant=t,"undefined"!=typeof module&&module.exports&&(module.exports=t)}).call(this);var pixelplace=[[49,46,47],[99,92,90],[129,119,107],[198,181,165],[255,237,212],[150,86,122],[202,112,145],[96,67,79],[136,79,94],[175,101,103],[195,124,107],[221,153,126],[233,181,140],[198,139,91],[140,89,74],[94,68,63],[225,173,86],[248,207,142],[239,220,118],[206,190,85],[157,159,55],[114,121,43],[81,94,46],[69,100,79],[80,134,87],[187,209,138],[91,84,108],[106,113,137],[122,148,156],[174,215,185]],q=new RgbQuant({colors:32,palette:pixelplace,reIndex:!0,dithKern:"FloydSteinberg",dithDelta:.05,useCache:!1});window.onload=function(){document.getElementById("dithKern").onchange=function(t){processImage()},document.getElementById("getimg").addEventListener("change",function(){var t=document.getElementById("getimg").files[0],i=new FileReader;i.onloadend=function(){document.getElementById("img").setAttribute("src",i.result),setTimeout(processImage,500)},t&&i.readAsDataURL(t)},!0),processImage()};
</script>
</head>
<body>
Select your image: <input type="file" id="getimg"/><br>
Conversion Strategy: <select id="dithKern">
<option value="">Default</option>
<option value="FloydSteinberg" selected>FloydSteinberg</option>
<option value="Stucki">Stucki</option><option value="Atkinson">Atkinson</option>
<option value="Jarvis">Jarvis</option>
<option value="Burkes">Burkes</option>
<option value="Sierra">Sierra</option>
<option value="TwoSierra">TwoSierra</option>
<option value="SierraLite">SierraLite</option>
<option value="FalseFloydSteinberg">FalseFloyd</option>
</select>
<br>
<a href="https://github.com/leeoniya/RgbQuant.js/">Github Reference!</a><br>
<img id="img" src="vpPlace.png" alt=""><br>
Converted image<br>
</body>
</html>