p5.js library for glitching images and binary files in the web browser.
cc teddavis.org 2020 –
Here are a few examples to get you going:
- image – demo / html / editor.p5js / p5live
- image-types – demo / html / editor.p5js / p5live
- webcam – demo / html / editor.p5js / p5live
- video – demo / html / editor.p5js / p5live
- binary-font – demo / html / editor.p5js / p5live
- almost-everything – demo / html / editor.p5js / p5live
- callback – demo / html / editor.p5js / p5live
- instance - demo / html
Download p5.glitch.js
and include with your p5.js sketch's index.html file.
Optionally clone/download the GitHub Repo.
Load remotely via jsdelivr CDN:
<script src="https://cdn.jsdelivr.net/npm/p5.glitch@latest/p5.glitch.js"></script>
p5.glitch is a class
, so after an instance has been attached to a variable, you'll need to use that prefix in front of every function listed below, ie: glitch.loadImage()
. This enables you to have multiple glitches running parallel. All examples below use glitch
as the instance prefix.
Create a global instance of p5.glitch:
let glitch;
function setup() {
createCanvas(windowWidth, windowHeight);
/* create glitch instance */
glitch = new Glitch();
/* optional settings */
// glitch.pixelate(1); // hard pixel edges (pixelDensity)
// glitch.errors(false); // hide any bad data warnings
// glitch.debug(); // show debugs - avoid if anything called in draw()
// glitch.debug(false); // hide debug
}
See instance demo above for using with p5.js instance mode.
Images can be live previewed within your sketch and browser:
/* load image */
glitch.loadType('jpg'); // specify jpeg file glitching, default
glitch.loadQuality(.25); // optionally crunch to low quality
glitch.loadImage('data/images/fish.png'); // load image by path
// glitch.loadImage(capture); // load existing p5.js image
/* reset bytes */
// glitch.resetBytes(); // reset glitch to original bytes if loaded in setup
/* sample glitching functions */
glitch.randomBytes(10); // randomize 10 bytes
glitch.replaceBytes(45, 127); // find + replace all
glitch.replaceHex('ffdb00430001','ffdb004300ff'); // jpg quant table
/* build and display image */
glitch.buildImage(); // creates image from glitched data
image(glitch.image, 0, 0); // display glitched image
/* save image */
glitch.saveImage('fish_glitched.jpg'); // save raw glitched file
// glitch.saveSafe('fish_glitched'); // save safe glitched file
// glitch.saveCanvas('fish_glitched'); // saves entire canvas
Binary data (any file) can be loaded, glitched, saved. Best in setup()
or on demand:
/* load binary file with callback when ready */
glitch.loadBytes('data/movies/fish.mp4', function(){
/* sample glitching functions */
glitch.randomBytes(100); // randomize 100 bytes
glitch.replaceBytes(45, 127); // find + replace all
/* save binary file */
glitch.saveBytes('fish_glitched.mp4'); // compiles and download
});
Throughout the reference sub-heads, the instance prefix has been left away for easier reading. Don't forget to include it during use (ie. glitch.image
).
Array containing list of available image/filetypes, based on browser, for image glitching.
print(glitch.types); // see list of available image types
Array of original and glitched bytes after running loadImage()
or loadBytes()
.
The bytesGlitched
array is updated with each glitch function. Use in combination with updateBytes()
for creating custom glitch functions.
After running buildImage()
, contains glitched bytes as p5.js image to display.
image(glitch.image, 0, 0); // image from top-left downward
imageMode(CENTER); // set center-out images
image(glitch.image, width / 2, height / 2); // draw in center of canvas
Automatically calculated dimensions to fill canvas when displaying image
.
image(glitch.image, 0, 0, glitch.width, glitch.height); // fills canvas
Use to force hard pixels when resizing (nearest neighbor). Sets the sketch to noSmooth()
and the canvas style imageRendering to pixelated. Optionally set the pixelDensity()
by including a newDensity value (constrainted from 0 to displayDensity()
). Only set within the setup()
.
glitch.pixelate(0.5);
Sets the image/type when converting loaded image to base64/bytes.
Check types
for list of available filetypes based on your browser (each support different ones).
glitch.loadType('image/png'); // complete type as processed
glitch.loadType('png'); // same as above, 'image/' inserted if missing
glitch.loadType(random(glitch.types)); // load random available types
// used before glitch.loadImage()
Sets the quality when converting loaded image to base64/bytes.
Only available for jpeg and webp. Number between 0.0 – 1.0
glitch.loadQuality(1.0); // set hi-quality
glitch.loadQuality(0.01); // set extremely low-quality
glitch.loadQuality(random(0.01, 1.0); // set random quality
// used before glitch.loadImage()
Load an image by string (filepath) or passing an existing p5.js image from the built-in loadImage()
or video/webcam. Optionally declare a callback
function to be run once loaded.
Each time function is called, bytes
+ bytesGlitched
are replaced. If a static image, simply load it once and use resetBytes()
to revert changes.
// load by filepath string
glitch.loadImage('data/images/fish.png');
// load p5.js image (same as above, useful if already loaded)
loadImage('data/images/fish.png', function(img){
glitch.loadImage(img);
});
// load using webcam (see p5.js example for capture)
glitch.loadImage(capture);
Compile any processed glitches into image
for displaying and saving. Optionally use a callback
function to display the compiled image after each glitch.
// basic usage before displaying image
glitch.buildImage(); // compile glitched data
image(glitch.image, 0, 0); // display image whenever compiled
// callback usage
glitch.randomBytes(1); // 1 random byte
glitch.buildImage(function(img){
image(img, width / 2, height * 0.25);
});
glitch.randomBytes(100); // 100 additional random bytes
glitch.buildImage(function(img){
image(img, width / 2, height * 0.75);
});
Downloads glitched image file from bytesGlitched
(live glitch = software may reject it).
Use custom fileName or defaults to p5.glitch_timestamp. File format extension used during loadImage()
is automatically added to filename suffix.
glitch.saveImage(); // saved as 'p5.glitch_######_######.ext' (ext = format)
glitch.saveImage('fish_glitched'); // saved as 'fish_glitched.ext' (ext = format)
Downloads a safe copy of the glitched image
. While saveImage()
still contains glitchy bytes (volatile and might not be able to upload or open in software), this safe copy is a normal image.
Use custom fileName or defaults to p5.glitch_timestamp. Add a custom fileType – accepts jpg or png is default for highest quality.
glitch.saveSafe(); // saved as 'p5.glitch_######_######_safe.png'
glitch.saveSafe('fish_glitched'); // saved as 'fish_glitched_safe.png'
glitch.saveSafe('fish_glitched', 'jpg'); // saved as 'fish_glitched_safe.jpg'
Saves the entire p5.js canvas incase compositing glitched images or used to create a 'safe' version of the glitch (stable image for sharing). Use custom fileName or defaults to p5.glitch. _canvas.png. Add a custom fileType – accepts jpg or png is default for highest quality.
glitch.saveCanvas(); // saved as 'p5.glitch_######_######_canvas.png'
glitch.saveCanvas('fish', 'jpg'); // saved as 'fish_canvas.jpg'
Load any binary file either by string (filepath) or passing a previously loaded array of bytes from p5.js loadBytes()
. Optionally declare a callback
function to be run once loaded.
// load by filepath string
glitch.loadBytes('data/movies/fish.png');
// load using p5.js loadBytes
loadBytes('data/movie/fish.png', function(loadedBytes){
glitch.loadBytes(loadedBytes, function(){
// print(glitch.bytes.length); // check size of loaded bytes
});
});
Compiles and downloads binary file from bytesGlitched
. Be sure to give same file format extension to fileName as your input file.
glitch.saveBytes('fish_glitched.mp4');
These functions should be called between the loading and saving/displaying of your binary/image.
Resets bytesGlitched
to the original bytes
array.
Especially useful if only using loadBytes()
or loadImage()
on demand (or in setup()
) to regularly reset the glitched bytes as needed.
glitch.resetBytes();
Constrains where in the file glitch functions randomBytes()
and replaceBytes()
are allowed to modify the bytes array. This is useful to help avoid breaking the header of a file. By default, limitStart is .2 (20% into the data) and limitStop is 1.0 (end of file). You can adjust this as often as needed throughout your sketch, providing just a new starting point, or and start and stop point.
glitch.limitBytes(0.5, 0.6); // only modify the middle 10% of file
Sets a single byte, at provided bytePos position, to a random value between 0 - 255. Can set position by decimal or hex.
glitch.randomByte(123); // the 123rd byte
glitch.randomByte('7b'); // the 123rd byte, using hex
Sets byteCount number of multiple random bytes to either a random value between 0 - 255, or optionally, the provided replaceVal. The replaceVal can be set by decimal or hex.
glitch.randomBytes(10); // set 10 random bytes, throughout data
glitch.randomBytes(100, 'ff'); // sets 100 random bytes to 'ff' (255)
Sets a single byte, at provided bytePos position, to the provided replaceVal. Both values can be set by decimal or hex.
glitch.replaceByte(123, 255); // replaces 123rd byte with value 255
glitch.replaceByte('7b', 'ff'); // same as above, in hex
Sets all bytes found from findVal to the provided replaceVal. Both values can be set by decimal or hex.
glitch.replaceBytes(42, 24); // replaces all bytes with 42 to 24
glitch.replaceBytes('ff', '00'); // replaces all (as hex) from 255 to 0
Use this for precise mishandling data that you know the hex structure of. While replaceBytes()
handles individual bytes from the array, replaceHex()
allows you to replace entire strings of data. Sets all bytes (as hex string) found from findVal to the provided replaceVal.
// modify jpg quantization table 1
glitch.replaceHex('ffdb00430001', 'ffdb004300ff'); // wootwoot!
// modify jpg quantization table 2
glitch.replaceHex('ffdb00430101', 'ffdb004301ff'); // soo colorful!
Here are some useful functions if creating your own glitch functions to manipulate the original bytes
or additive bytesGlitched
.
Safely find newPos position within the bytesGlitched
, or optionally a custom bytes array. newPos position can be set by decimal or hex.
// custom glitch function
let newBytes = glitch.bytesGlitched.slice(); // clone glitched array
// find position in byte array
let randomPos = random(0, glitch.bytesGlitched.length);
let safePos = glitch.parsePosition(randomPos);
newBytes[safePos] = 255; // change single random byte
// ... updateBytes() to save changes
Safely convert newVal to decimal byte if given a floating point or string. newVal value can be set by decimal or hex.
// custom glitch function
let newBytes = glitch.bytesGlitched.slice(); // clone glitched array
// find position in byte array
newBytes[50] = glitch.parseByte(random(255)); // single random value
// ... updateBytes() to save changes
This is automatically called at the end of each glitch function to set both the bytesGlitched
and base64Glitched
variables for compiling and displaying thereafter. Pass newBytes a modified clone original or glitched byte array.
// custom glitch function
let newBytes = glitch.bytes.slice(); // clone original data array
newBytes[50] = glitch.parseByte(24); // change single byte
glitch.updateBytes(newBytes); // updates glitch.bytesGlitched
// ... display/save/etc have current changes
Convert byte array to hex for string based manipulations with bytesToHex()
. Convert back to bytes with hexToBytes()
before passing modified data to updateBytes()
.
// custom hex glitch function
let tempHex = glitch.bytesToHex(glitch.bytes); // bytes array to hex
tempHex = tempHex.split('ffff').join('cccc'); // find + replace hex
let newBytes = hexToBytes(tempHex);
glitch.updateBytes(newBytes); // updates glitch.bytesGlitched
// ... display/save/etc have current changes
Occasionally you'll kill the image, producing a p5.js error in the console. If you want to ignore all errors, disable them within the setup()
:
glitch.errors(false); // disable error logging
p5.disableFriendlyErrors = true; // disable p5.js warnings about bad images
If you want to follow the progress of on-demand load/save bytes, enable debug()
. Be sure to disable if processing anything within the draw()
otherwise you'll flood the console.
glitch.debug(); // activate debug
glitch.debug(false); // disable debug (default)
Found a bug, missing feature, and/or created a project with p5.glitch, let me know!
Create an issue on GitHub.