Skip to content

Commit

Permalink
v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mster committed Apr 6, 2020
1 parent abbb3ba commit b13e784
Show file tree
Hide file tree
Showing 9 changed files with 700 additions and 124 deletions.
46 changes: 25 additions & 21 deletions README.md
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)

13 changes: 13 additions & 0 deletions lib/error.js
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
19 changes: 5 additions & 14 deletions lib/modes/blurbobb.js
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
}
19 changes: 5 additions & 14 deletions lib/modes/schifty.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
'use strict'

const jpeg = require('jpeg-js')
const debug = require('debug')('mode:schifty')

module.exports = function (original) {
const decoded = jpeg.decode(original)
let data = Buffer.from(decoded.data)
const bitmapData = original.bitmap.data
let data = Buffer.from(bitmapData)

let size = Math.random() * 1024 * 4
let total = size
let temp = []
const storage = []

for (let i = 0; i < decoded.data.length; i++) {
for (let i = 0; i < data.length; i++) {
if (i < total) temp.push(data[i])
else {
storage.push(Buffer.from(temp))
Expand All @@ -23,13 +20,7 @@ module.exports = function (original) {
}

data = Buffer.concat(storage)
original.bitmap.data = data

const jpegEncode = jpeg.encode({
data: data,
width: decoded.width,
height: decoded.height
})
debug('Encoding successful.')

return Buffer.from(jpegEncode.data)
return original
}
11 changes: 11 additions & 0 deletions lib/modes/template
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
}
92 changes: 50 additions & 42 deletions lib/mosh.js
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}`)
}
17 changes: 0 additions & 17 deletions lib/util.js

This file was deleted.

Loading

0 comments on commit b13e784

Please sign in to comment.