memoscan
← all memos

Memo 0x4bdc9bc6…1bc6b2 on Ethereum

0xb81bf680…7cf2·#25,052,493·view on Etherscan
W_R`@_ U_R`@_ U_R`@_ U`Wa faCfV[a naEPV[c8Wa!-aCfV[a!5aEPV[`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef`ghijklmnopqrstuvwxyz0123456789-_MELANCHOLIA is a library of dyna` mic text-image compositions stor`@ed and generated entirely on the`` blockchain. Each composition re`appropriates an historical print` from a master of its era and tr`W_R`@_ U_R`@_ U_R`a9EV[PPPPPPPPPa9[V[PUa9[V[PPPPPPPa9[V[PUa9[V[PPPPPa9[V[PPWa>őaE4V[a>TV[`a>#V[PPPPPPPa>8V[PPPPPPUa>8V[PPPPPa>8V[PPPPUa>8V[PPPPa>8V[PUPa>8V[PhaD*V[a=<V[`@Qcf\{\u00000123456789abcdefbtno0123456789abcdef` <!doctype html><meta charset=utf-8><style> html,body{margin:0;height:100%}body{background:#000;color:#fff;overflow:hidden;display:flex;align-items:center;justify-content:center} pre{margin:0;font-family:ui-monospace,monospace;letter-spacing:-0.175em;font-feature-settings:"liga" 0;text-shadow:0 0 .5px #fff,0 0 .5px #fff;-webkit-text-stroke:.5px #fff} </style><pre id=o></pre><script> // Params: window.P (contract-injected) or URL query (testing). (()=>{ const q=new URLSearchParams(location.search),g=k=>window.P&&k in window.P?window.P[k]:q.get(k); const n=(k,d)=>{const v=g(k);return v==null||isNaN(+v)?d:+v}; const P={src:g('src')||'https://upload.wikimedia.org/wikipedia/commons/thumb/d/d7/Albrecht_D%C3%9CRer_-_Melencolia_I_-_Google_Art_Project.jpg/1920px-Albrecht_D%C3%9CRer_-_Melencolia_I_-_Google_Art_Project.jpg',scale:n('scale',0.15),contrast:n('contrast',0.255),brightness:n('brightness',0.4),gamma:n('gamma',0.93),threshold:n('threshold',109),blur:n('blur',0.5),sharpen:n('sharpen',0.53),downscale:n('downscale',0.91),font:n('font',5),cropL:n('cropL',0),cropR:n('cropR',0),cropT:n('cropT',0),cropB:n('cropB',0),invert:g('invert')==='true'||g('invert')===true}; const D=[[1,2,4,64],[8,16,32,128]],O=document.getElementById('o'); O.style.fontSize=P.font+'px';O.style.lineHeight=Math.max(1,Math.round(P.font*0.95))+'px'; // Deterministic pipeline: createImageBitmap with colorSpaceConversion:'none' // (no Safari ICC color management on JPEG decode), JS box resample (no // browser-specific imageSmoothingQuality kernel), JS gaussian blur (no // ctx.filter quirks). Identical bytes in Chrome and Safari. function bx(s,sw,sh,tw,th){if(tw===sw&&th===sh)return s;const o=new Float32Array(tw*th*3),sx=sw/tw,sy=sh/th;for(let y=0;y<th;y++){const y0=y*sy,y1=(y+1)*sy,iy0=Math.floor(y0),iy1=Math.min(sh,Math.ceil(y1));for(let x=0;x<tw;x++){const x0=x*sx,x1=(x+1)*sx,ix0=Math.floor(x0),ix1=Math.min(sw,Math.ceil(x1));let r=0,g=0,b=0,w=0;for(let yy=iy0;yy<iy1;yy++){const fy=Math.min(y1,yy+1)-Math.max(y0,yy);for(let xx=ix0;xx<ix1;xx++){const fx=Math.min(x1,xx+1)-Math.max(x0,xx),ww=fy*fx,i=(yy*sw+xx)*3;r+=s[i]*ww;g+=s[i+1]*ww;b+=s[i+2]*ww;w+=ww}}const j=(y*tw+x)*3;o[j]=r/w;o[j+1]=g/w;o[j+2]=b/w}}return o} function gb(b,w,h,sg){if(sg<=0)return;const r=Math.max(1,Math.ceil(sg*3)),k=new Float32Array(r*2+1),s2=2*sg*sg;let ks=0;for(let i=-r;i<=r;i++){const v=Math.exp(-(i*i)/s2);k[i+r]=v;ks+=v}for(let i=0;i<k.length;i++)k[i]/=ks;const t=new Float32Array(b.length);for(let y=0;y<h;y++)for(let x=0;x<w;x++){let v=0;for(let i=-r;i<=r;i++){const xx=x+i<0?0:x+i>=w?w-1:x+i;v+=b[y*w+xx]*k[i+r]}t[y*w+x]=v}for(let y=0;y<h;y++)for(let x=0;x<w;x++){let v=0;for(let i=-r;i<=r;i++){const yy=y+i<0?0:y+i>=h?h-1:y+i;v+=t[yy*w+x]*k[i+r]}b[y*w+x]=v}} (async()=>{ let bm;try{const rs=await fetch(P.src,{mode:'cors'});if(!rs.ok)throw 0;bm=await createImageBitmap(await rs.blob(),{colorSpaceConversion:'none'})}catch(e){O.textContent='[the source image seems to be unavailable, replace it with another]';return} let sw=bm.width,sh=bm.height; const c=document.createElement('canvas');c.width=sw;c.height=sh;const cx=c.getContext('2d',{willReadFrequently:true,colorSpace:'srgb'});cx.drawImage(bm,0,0);const id=cx.getImageData(0,0,sw,sh).data; let rgb=new Float32Array(sw*sh*3);for(let i=0,j=0;j<id.length;i+=3,j+=4){rgb[i]=id[j];rgb[i+1]=id[j+1];rgb[i+2]=id[j+2]} if(P.cropL>0||P.cropR>0||P.cropT>0||P.cropB>0){const x0=Math.round(sw*P.cropL),y0=Math.round(sh*P.cropT),w=Math.max(1,Math.round(sw*(1-P.cropL-P.cropR))),h=Math.max(1,Math.round(sh*(1-P.cropT-P.cropB))),cc=new Float32Array(w*h*3);for(let y=0;y<h;y++)for(let x=0;x<w;x++){const si=((y0+y)*sw+(x0+x))*3,di=(y*w+x)*3;cc[di]=rgb[si];cc[di+1]=rgb[si+1];cc[di+2]=rgb[si+2]}rgb=cc;sw=w;sh=h} let pw=sw,ph=sh; if(P.downscale<1){const r=sw/sh,t=Math.round(Math.max(sw,sh)*P.downscale),dw=r>=1?t:Math.round(t*r),dh=r>=1?Math.round(t/r):t;rgb=bx(rgb,pw,ph,dw,dh);pw=dw;ph=dh} const cw=Math.max(1,Math.round(sw*P.scale)),ch=Math.max(1,Math.round(sh*P.scale/2)),W=cw*2,H=ch*4; const sm=bx(rgb,pw,ph,W,H); const b=new Float32Array(W*H);for(let i=0,j=0;i<b.length;i++,j+=3)b[i]=0.299*sm[j]+0.587*sm[j+1]+0.114*sm[j+2]; gb(b,W,H,P.blur); const cf=(1+P.contrast)/Math.max(1e-6,1-P.contrast); for(let i=0;i<b.length;i++){let v=b[i]/255;v=Math.pow(Math.max(0,v),1/P.gamma);v=(v-0.5)*cf+0.5+P.brightness;if(P.invert)v=1-v;b[i]=Math.max(0,Math.min(1,v))*255} if(P.sharpen>0){const k=P.sharpen,s2=new Float32Array(b);for(let y=1;y<H-1;y++)for(let x=1;x<W-1;x++){const i=y*W+x,v=s2[i]*(1+4*k)-k*(s2[i-1]+s2[i+1]+s2[i-W]+s2[i+W]);b[i]=Math.max(0,Math.min(255,v))}} const t=128+P.threshold,bn=new Uint8Array(W*H); for(let y=0;y<H;y++)for(let x=0;x<W;x++){const i=y*W+x,o=b[i],n=o<t?0:255;bn[i]=n?1:0;const e=(o-n)/8,f=(dx,dy)=>{const nx=x+dx,ny=y+dy;if(nx>=0&&nx<W&&ny>=0&&ny<H)b[ny*W+nx]+=e};f(1,0);f(2,0);f(-1,1);f(0,1);f(1,1);f(0,2)} let s='';for(let cy=0;cy<ch;cy++){for(let cx=0;cx<cw;cx++){let c=0;for(let dx=0;dx<2;dx++)for(let dy=0;dy<4;dy++)if(!bn[(cy*4+dy)*W+cx*2+dx])c|=D[dx][dy];s+=String.fromCharCode(0x2800+c)}if(cy<ch-1)s+='\n'} O.textContent=s;fit(); })(); function fit(){O.style.transform='';const r=O.getBoundingClientRect();if(!r.width||!r.height)return;const lh=parseInt(O.style.lineHeight)||1,w=Math.min(innerWidth/r.width,innerHeight/r.height,1),sn=Math.floor(lh*w),sc=sn>=1?sn/lh:w;if(sc<1)O.style.transform='scale('+sc+')'} addEventListener('resize',fit); })(); </script>