Compatible with Newtek LightWave 9.6 and above.
// LScript Image Filter - www.StephenCulley.co.uk // // web address: http://www.stephenculley.co.uk // email address: email@stephenculley.co.uk /* LScript Image Filter - Digital Artifacts Image_DigitalArtifacts.ls */ @version 2.5 @warnings @script image @name *Digital Artifacts // Title sTitle = "*Digital Artifacts"; // Version sVersion = "v1.0"; iBlockSize = 8; iLifeRed = 2; iLifeGreen = 2; iLifeBlue = 2; nErrorRed = 0.03; nErrorGreen = 0.03; nErrorBlue = 0.03; bColorSync = false; aBlock = nil; // Block // Control ctrl_pr0,ctrl_c0,ctrl_c1,ctrl_c2,ctrl_c3,ctrl_c4,ctrl_c5,ctrl_c6,ctrl_c7; create { setdesc(sTitle); } process: ifo { // Error if(ifo.width < 1 || ifo.height < 1){return;} // Variable iBlock = 1; iBlockMultiplier = 1 / (iBlockSize * iBlockSize); iGridX = floor(ifo.width / iBlockSize); iGridY = floor(ifo.height / iBlockSize); _nErrorRed = nErrorRed * (iBlockSize * iBlockSize); _nErrorGreen = nErrorGreen * (iBlockSize * iBlockSize); _nErrorBlue = nErrorBlue * (iBlockSize * iBlockSize); // Init Block if(aBlock.size() <> (iGridX * iGridY) || ifo.frame == 0) { for(b = 1; b <= (iGridX * iGridY); ++b) { aBlock[b,1] = 0; // Red Count aBlock[b,2] = 0; // Green Count aBlock[b,3] = 0; // Blue Count aBlock[b,4] = 0.0; // Red aBlock[b,5] = 0.0; // Green aBlock[b,6] = 0.0; // Blue } } iProgress = iGridX * iGridY; if(runningUnder() != SCREAMERNET) moninit(iProgress); for(gy = 0;gy <= iGridY - 1; ++gy) { for(gx = 0;gx <= iGridX - 1; ++gx) { _gx = gx * iBlockSize; _gy = gy * iBlockSize; r = 0; g = 0; b = 0; // Average for(i = 1;i <= iBlockSize; ++i) { for(j = 1;j <= iBlockSize; ++j) { r += ifo.red[j + _gx,i + _gy]; // Red g += ifo.green[j + _gx,i + _gy]; // Green b += ifo.blue[j + _gx,i + _gy]; // Blue } } r *= iBlockMultiplier; g *= iBlockMultiplier; b *= iBlockMultiplier; // Difference rd = 0; gd = 0; bd = 0; for(i = 1;i <= iBlockSize; ++i) { for(j = 1;j <= iBlockSize; ++j) { rd += abs(ifo.red[j + _gx,i + _gy] - r); gd += abs(ifo.green[j + _gx,i + _gy] - g); bd += abs(ifo.blue[j + _gx,i + _gy] - b); } } // Update Block if(bColorSync) { if((aBlock[iBlock,1] <= 0 && rd < _nErrorRed) || (aBlock[iBlock,2] <= 0 && gd < _nErrorGreen) || (aBlock[iBlock,3] <= 0 && bd < _nErrorBlue)) { c = random(1,3); aBlock[iBlock,1] = c; aBlock[iBlock,2] = c; aBlock[iBlock,3] = c; } aBlock[iBlock,4] = r; aBlock[iBlock,5] = g; aBlock[iBlock,6] = b; } else { if(aBlock[iBlock,1] <= 0 && rd < _nErrorRed) // Red { aBlock[iBlock,1] = random(1,iLifeRed); aBlock[iBlock,4] = r; } if(aBlock[iBlock,2] <= 0 && gd < _nErrorGreen) // Green { aBlock[iBlock,2] = random(1,iLifeGreen); aBlock[iBlock,5] = g; } if(aBlock[iBlock,3] <= 0 && bd < _nErrorBlue) // Blue { aBlock[iBlock,3] = random(1,iLifeBlue); aBlock[iBlock,6] = b; } } // Read Block rd = aBlock[iBlock,1]; --aBlock[iBlock,1]; r = aBlock[iBlock,4]; gd = aBlock[iBlock,2]; --aBlock[iBlock,2]; g = aBlock[iBlock,5]; bd = aBlock[iBlock,3]; --aBlock[iBlock,3]; b = aBlock[iBlock,6]; // Draw Block for(i = 1;i <= iBlockSize; ++i) { for(j = 1;j <= iBlockSize; ++j) { if(rd > 0){ifo.red[j + _gx,i + _gy] = r;} if(gd > 0){ifo.green[j + _gx,i + _gy] = g;} if(bd > 0){ifo.blue[j + _gx,i + _gy] = b;} } } ++iBlock; if(runningUnder() != SCREAMERNET) if(monstep()) return; } } } // CLIP clip: min,max,n { if(n < min) n = min; if(n > max) n = max; return(n); } load: what,io { if(what == SCENEMODE) { bColorSync = io.read().asInt(); iBlockSize = io.read().asInt(); iLifeRed = io.read().asInt(); iLifeGreen = io.read().asInt(); iLifeBlue = io.read().asInt(); nErrorRed = io.read().asNum(); nErrorGreen = io.read().asNum(); nErrorBlue = io.read().asNum(); } } save: what,io { if(what == SCENEMODE) { io.writeln(bColorSync); io.writeln(iBlockSize); io.writeln(iLifeRed); io.writeln(iLifeGreen); io.writeln(iLifeBlue); io.writeln(nErrorRed); io.writeln(nErrorGreen); io.writeln(nErrorBlue); } } options { reqbegin(sTitle + " " + sVersion); // Control ctrl_pr0 = ctlpopup("Preset",1, @"Low", "Medium", "High", "Extreme"@); ctlsep(); ctrl_c0 = ctlinteger("Block Size",iBlockSize); ctrl_c1 = ctlcheckbox("Color Sync",bColorSync); ctrl_c2 = ctlinteger("Life Red",iLifeRed); ctrl_c3 = ctlinteger(" Green",iLifeGreen); ctrl_c4 = ctlinteger(" Blue",iLifeBlue); ctrl_c5 = ctlpercent("Error Red",nErrorRed); ctrl_c6 = ctlpercent(" Green",nErrorGreen); ctrl_c7 = ctlpercent(" Blue",nErrorBlue); // Developer ctlsep(); ctrl_dev0 = ctltext("","developer: Stephen Culley","http://www.stephenculley.co.uk"); // Refresh ctlrefresh(ctrl_pr0,"refresh_preset"); // Preset ctlrefresh(ctrl_c0,"refresh_c0"); // Block Size ctlrefresh(ctrl_c2,"refresh_c2"); // Life Red ctlrefresh(ctrl_c3,"refresh_c3"); // Life Green ctlrefresh(ctrl_c4,"refresh_c4"); // Life Blue ctlrefresh(ctrl_c5,"refresh_c5"); // Error Red ctlrefresh(ctrl_c6,"refresh_c6"); // Error Green ctlrefresh(ctrl_c7,"refresh_c7"); // Error Blue return if !reqpost(); iBlockSize = max(1,getvalue(ctrl_c0)); bColorSync = getvalue(ctrl_c1); iLifeRed = max(1,getvalue(ctrl_c2)); iLifeGreen = max(1,getvalue(ctrl_c3)); iLifeBlue = max(1,getvalue(ctrl_c4)); iErroRed = max(0.0,getvalue(ctrl_c5)); iErrorGreen = max(0.0,getvalue(ctrl_c6)); iErrorBlue = max(0.0,getvalue(ctrl_c7)); reqend(); } refresh_preset:value { if(value == 1) // Low { setvalue(ctrl_c0,8); // Block Size setvalue(ctrl_c1,0); // Sync Color setvalue(ctrl_c2,1); // Life Red setvalue(ctrl_c3,1); // Life Green setvalue(ctrl_c4,1); // Life Blue setvalue(ctrl_c5,0.02); // Error Red setvalue(ctrl_c6,0.02); // Error Green setvalue(ctrl_c7,0.02); // Error Blue } if(value == 2) // Medium { setvalue(ctrl_c0,8); // Block Size setvalue(ctrl_c1,0); // Sync Color setvalue(ctrl_c2,2); // Life Red setvalue(ctrl_c3,2); // Life Green setvalue(ctrl_c4,2); // Life Blue setvalue(ctrl_c5,0.02); // Error Red setvalue(ctrl_c6,0.03); // Error Green setvalue(ctrl_c7,0.04); // Error Blue } if(value == 3) // High { setvalue(ctrl_c0,8); // Block Size setvalue(ctrl_c1,0); // Sync Color setvalue(ctrl_c2,3); // Life Red setvalue(ctrl_c3,3); // Life Green setvalue(ctrl_c4,3); // Life Blue setvalue(ctrl_c5,0.02); // Error Red setvalue(ctrl_c6,0.04); // Error Green setvalue(ctrl_c7,0.06); // Error Blue } if(value == 4) // Extreme { setvalue(ctrl_c0,8); // Block Size setvalue(ctrl_c1,0); // Sync Color setvalue(ctrl_c2,9); // Life Red setvalue(ctrl_c3,9); // Life Green setvalue(ctrl_c4,9); // Life Blue setvalue(ctrl_c5,0.1); // Error Red setvalue(ctrl_c6,0.1); // Error Green setvalue(ctrl_c7,0.1); // Error Blue } } refresh_c0:value // Block Size { iBlockSize = max(1,value); setvalue(ctrl_c0,iBlockSize); } refresh_c2:value // Life Red { iLifeRed = max(1,value); setvalue(ctrl_c2,iLifeRed); } refresh_c3:value // Life Green { iLifeGreen = max(1,value); setvalue(ctrl_c3,iLifeGreen); } refresh_c4:value // Life Blue { iLifeBlue = max(1,value); setvalue(ctrl_c4,iLifeBlue); } refresh_c5:value // Error Red { nErrorRed = clip(0.0,1.0,value); setvalue(ctrl_c5,nErrorRed); } refresh_c6:value // Error Green { nErrorGreen = clip(0.0,1.0,value); setvalue(ctrl_c6,nErrorGreen); } refresh_c7:value // Error Blue { nErrorBlue = clip(0.0,1.0,value); setvalue(ctrl_c7,nErrorBlue); }
All scripts available at my Google Drive at
https://drive.google.com/open?id=1cR_q2GVUAJHumic1-A3eXV16acQnVTWs
Cool lscript, thank you.
ReplyDeleteWould it possible to add envelopes, to be able to animate the blockiness over time?
Do you mean opacity of the effect, or just the controls? The only control that would be difficult to change would be block size due it it needing to change array sizes and data would be lost. Otherwise, I could make it have envelopes. Maybe add opacity as well tho that will slow down processing?
DeleteStephen
It would be the size of the blocks (Block Size) that would be cool to be able to animate over time.
DeleteI guess it would be like a zoom effect into an image so the blocky pixels look like they are getting bigger.
This is an old script so what I'll do is create a quick script to generate block effects since to be able to change block size would require a slight rewrite to implement. I'll sort an example of it over tomorrow.
DeleteStephen