-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
700 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,41 @@ | ||
# Datamosh | ||
|
||
Mess around with image data using *buffers*, create some interesting & artistic results, **profit**. | ||
Mess around with image data using _buffers_, create some interesting & artistic results, **profit**. | ||
|
||
## API | ||
### mosh(readFrom [, writeOut] [, config]) | ||
* `readFrom`: Path to original image that you wish to mosh. Currently only `*.jpg` and `*.jpeg` file formats are supported. | ||
* `writeOut` (optional): Path to write the resulting image. If unspecified, `mosh(...)` will return the resulting image data as a buffer. | ||
* `config` (optional): Configuration options for the datamoshing. | ||
* `mode`: The mode to choose when moshing the supplied image. If no mode is specified, it will be chosen at random. | ||
|
||
### mosh ( options, cb ) | ||
|
||
- `options`: | ||
- `read`: (Required) Path to original image that you wish to mosh. | ||
Supported types: `.jpg, .jpeg, .png, .bmp, .tiff, .gif`. | ||
- `write`: Path to write the resulting image. If unspecified, `mosh()` will return the resulting image data (Jimp). | ||
- `mode`: The mode to choose when moshing the supplied image. If no mode is specified, it will be chosen at random. | ||
- `cb`: `function(error, data)` the callback function | ||
|
||
## Example | ||
|
||
```js | ||
const mosh = require('./'); | ||
|
||
(async function jumpInThePit () { | ||
try { | ||
const moshedData = await mosh( | ||
'path/to/read/image.jpg', | ||
'path/to/write/image_moshed.jpg', | ||
{ mode: 'blurbobb' } | ||
) | ||
} catch (error) { | ||
console.log(error) | ||
} | ||
})(); | ||
;(function jumpInThePit () { | ||
require('./index')( | ||
{ | ||
read: '/home/m/Desktop/0.jpeg', | ||
write: '/home/m/Desktop/1.jpeg', | ||
mode: 'blurbobb' | ||
}, | ||
(err, data) => { | ||
if (err) return console.error(err) | ||
|
||
console.log('Moshing Completed!') | ||
} | ||
) | ||
})() | ||
``` | ||
|
||
**Original** | ||
|
||
![cute_kibby](https://user-images.githubusercontent.com/15038724/63730272-7bea3a00-c81f-11e9-9180-15d0d983adaf.jpg) | ||
|
||
**M̵̟̰̬̼͐͂͛̀̀͒̋̄͗͘͝͝o̵̹̐͗͌s̷̛͍̞͍̤̘̜̎̄̆͊̃̆́͋͋̏̆̕h̸̺̦͍̝̳̞̮̮̝̐͌̏̓̌̾͠͠ͅe̶̛̙̯̭̳͕̗͒̓̓̂̋̈́̐̄̕d̴̟̩̖̟̖̻̱̰̥̗̜̪̊** using `schifty` mode. | ||
**M̵̟̰̬̼͐͂͛̀̀͒̋̄͗͘͝͝o̵̹̐͗͌s̷̛͍̞͍̤̘̜̎̄̆͊̃̆́͋͋̏̆̕h̸̺̦͍̝̳̞̮̮̝̐͌̏̓̌̾͠͠ͅe̶̛̙̯̭̳͕̗͒̓̓̂̋̈́̐̄̕d̴̟̩̖̟̖̻̱̰̥̗̜̪̊** using `schifty` mode. | ||
|
||
![moshed_kibby](https://user-images.githubusercontent.com/15038724/63730276-7e4c9400-c81f-11e9-84e1-2cd37eeb40bf.jpg) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
'use strict' | ||
|
||
class MoshError extends Error { | ||
constructor (message, options) { | ||
super(message) | ||
this.name = this.constructor.name | ||
this.message = message | ||
this.options = Object.assign({}, options) | ||
Error.captureStackTrace(this, this.constructor) | ||
} | ||
} | ||
|
||
module.exports = MoshError |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,17 @@ | ||
'use strict' | ||
|
||
const jpeg = require('jpeg-js') | ||
const debug = require('debug')('mode:blurbobb') | ||
|
||
module.exports = function (original) { | ||
const decoded = jpeg.decode(original) | ||
const data = Buffer.from(decoded.data) | ||
const bitmapData = original.bitmap.data | ||
const data = Buffer.from(bitmapData) | ||
|
||
let counter = 0 | ||
for (let i = 0; i < decoded.data.length; i++) { | ||
for (let i = 0; i < data.length; i++) { | ||
if (counter < 64) data[i] = Math.random() * 255 | ||
|
||
counter++ | ||
if (counter > 128) counter = Math.random() * 128 | ||
} | ||
|
||
const jpegEncode = jpeg.encode({ | ||
data: data, | ||
width: decoded.width, | ||
height: decoded.height | ||
}) | ||
debug('Encoding successful.') | ||
|
||
return Buffer.from(jpegEncode.data) | ||
original.bitmap.data = data | ||
return original | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
'use strict' | ||
|
||
module.exports = function (original) { | ||
const bitmapData = original.bitmap.data | ||
const data = Buffer.from(bitmapData) | ||
|
||
// manipulate data here | ||
|
||
original.bitmap.data = data | ||
return original | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,77 @@ | ||
'use strict' | ||
|
||
const debug = require('debug')('mosh') | ||
const Jimp = require('jimp') | ||
|
||
const debug = require('util').debuglog('mosh') | ||
const path = require('path') | ||
const { promisify } = require('util') | ||
const { writeFile: write, readFile: read } = require('fs') | ||
|
||
const writeFile = promisify(write) | ||
const readFile = promisify(read) | ||
|
||
const { throwMoshError } = require('./util') | ||
|
||
module.exports = mosh | ||
const MoshError = require('./error') | ||
|
||
const MODES = { | ||
blurbobb: require('./modes/blurbobb'), | ||
schifty: require('./modes/schifty') | ||
} | ||
|
||
async function mosh (readFrom, writeOut, config) { | ||
module.exports = mosh | ||
|
||
function mosh (options, cb) { | ||
debug('Moshing started.') // it's cool cuz it's nerdy. | ||
|
||
/* Only *.jpeg and *.jpeg are currently supported */ | ||
const filename = path.basename(readFrom) | ||
if (!(/^[a-zA-Z0-9]*.jpg$/.test(filename) || /^[a-zA-Z0-9]*.jpeg$/.test(filename))) { | ||
return throwMoshError('Only *.jpg OR *.jpeg file formats are supported.') | ||
if (!options || !options.read) { | ||
cb(new MoshError('Error: options.read is a required parameter')) | ||
return | ||
} | ||
|
||
if (config == null) config = {} | ||
const { read, write, mode } = options | ||
|
||
/* Read original file */ | ||
let original | ||
try { | ||
original = await readFile(readFrom) | ||
} catch (error) { | ||
return throwMoshError(error) | ||
const filename = path.basename(read) | ||
if ( | ||
!( | ||
filename.length < 256 && | ||
(/^[a-zA-Z0-9]*.jpg$/.test(filename) || | ||
/^[a-zA-Z0-9]*.jpeg$/.test(filename) || | ||
/^[a-zA-Z0-9]*.png$/.test(filename) || | ||
/^[a-zA-Z0-9]*.bmp$/.test(filename) || | ||
/^[a-zA-Z0-9]*.tiff$/.test(filename) || | ||
/^[a-zA-Z0-9]*.gif$/.test(filename)) | ||
) | ||
) { | ||
cb(new MoshError('Only *.jpg OR *.jpeg file formats are supported.')) | ||
return | ||
} | ||
debug(`Read successful: ${readFrom}`) | ||
|
||
/* If mode is unset, randomly select one */ | ||
const mode = config.mode == null | ||
? Object.keys(MODES)[Math.floor(Math.random() * Object.keys(MODES).length)] | ||
: config.mode | ||
debug(`Mode selected: ${mode}`) | ||
const _mode = | ||
mode == null | ||
? Object.keys(MODES)[ | ||
Math.floor(Math.random() * Object.keys(MODES).length) | ||
] | ||
: mode | ||
debug(`Mode selected: ${_mode}`) | ||
|
||
/* lean on jimp for img data */ | ||
Jimp.read(read) | ||
.then(doMosh) | ||
.then(writeMosh) | ||
.catch(onError) | ||
|
||
/* Mosh image depending on mode */ | ||
let post | ||
try { | ||
post = MODES[mode](original) | ||
} catch (error) { | ||
return throwMoshError(`Unsupported mosh mode. Supported modes: ${Object.keys(MODES).join(', ')}`) | ||
function doMosh (original) { | ||
debug('Moshing') | ||
return MODES[_mode](original) | ||
} | ||
debug('Mosh complete') | ||
|
||
/* Return raw data if `writeOut` location is unspecified */ | ||
if (writeOut == null) { | ||
debug('`writeOut` is null. Returning raw image data.') | ||
return post | ||
function writeMosh (moshed) { | ||
if (write) { | ||
debug('Mosh complete - writing out') | ||
moshed.write(write, cb) | ||
} else { | ||
debug('Mosh complete - calling back with img data') | ||
cb(null, moshed) | ||
} | ||
} | ||
|
||
/* Write image */ | ||
try { | ||
writeFile(writeOut, post) | ||
} catch (error) { | ||
return throwMoshError(error) | ||
function onError (error) { | ||
cb(new MoshError(error)) | ||
} | ||
debug(`Write successful: Image written to: ${writeOut}`) | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.