From 24f614b0045bdb95f9744286723251d64fcbb22e Mon Sep 17 00:00:00 2001 From: Dragon Fire Date: Thu, 2 Jul 2020 18:42:38 -0400 Subject: [PATCH] TONS of new image editing commands --- README.md | 9 ++- commands/edit-image/emboss.js | 50 ++++++++++++++++ commands/edit-image/implode.js | 57 ++++++++++++++++++ .../{magik.js => liquid-rescale.js} | 10 ++-- commands/edit-image/noise.js | 60 +++++++++++++++++++ commands/edit-image/oil-painting.js | 51 ++++++++++++++++ commands/edit-image/swirl.js | 57 ++++++++++++++++++ package.json | 2 +- 8 files changed, 288 insertions(+), 8 deletions(-) create mode 100644 commands/edit-image/emboss.js create mode 100644 commands/edit-image/implode.js rename commands/edit-image/{magik.js => liquid-rescale.js} (84%) create mode 100644 commands/edit-image/noise.js create mode 100644 commands/edit-image/oil-painting.js create mode 100644 commands/edit-image/swirl.js diff --git a/README.md b/README.md index 9a5328fb..4d5fa995 100644 --- a/README.md +++ b/README.md @@ -243,7 +243,7 @@ in the appropriate channel's topic to use it. ## Commands -Total: 515 +Total: 520 ### Utility: @@ -592,6 +592,7 @@ Total: 515 * **desaturate:** Draws an image or a user's avatar but desaturated. * **dexter:** Draws an image or a user's avatar over the screen of Dexter from Pokémon. * **distort:** Draws an image or a user's avatar but distorted. +* **emboss:** Draws an image or a user's avatar but embossed. * **fire-frame:** Draws a fiery border over an image or a user's avatar. * **fish-eye:** Draws an image or a user's avatar but with a fish-eye lens. * **frame:** Draws a frame around an image or a user's avatar. @@ -604,13 +605,16 @@ Total: 515 * **highway-sign:** Sends a highway sign sign with the text of your choice. * **hollywood-star:** Sends a Hollywood Walk of Fame star with the name of your choice. * **ifunny:** Draws an image with the iFunny logo. +* **implode:** Draws an image or a user's avatar but imploded. * **invert:** Draws an image or a user's avatar but inverted. * **jeopardy-question:** Sends a Jeopardy Question with the text of your choice. -* **magik:** Draws an image or a user's avatar but with liquid rescale from ImageMagick. +* **liquid-rescale:** Draws an image or a user's avatar but with liquid rescale from ImageMagick. * **minecraft-skin:** Sends the Minecraft skin for a user. * **mirror:** Draws an image or a user's avatar but mirrored on the X/Y axis (or both). * **needs-more-jpeg:** Draws an image or a user's avatar as a low quality JPEG. * **newspaper:** Creates a fake newspaper with the headline and body of your choice. +* **noise:** Draws an image or a user's avatar but with noise. +* **oil-painting:** Draws an image or a user's avatar but with oil paints. * **pixelize:** Draws an image or a user's avatar pixelized. * **pokemon-fusion:** Fuses two Generation I Pokémon together. * **police-tape:** Draws police tape over an image or a user's avatar. @@ -629,6 +633,7 @@ Total: 515 * **square:** Draws an image or a user's avatar as a square. * **squish:** Draws an image or a user's avatar but squished across the X or Y axis. * **subtitle:** Adds subtitles to an image. +* **swirl:** Draws an image or a user's avatar but swirled. * **tint:** Draws an image or a user's avatar but tinted a specific color. * **tweet:** Sends a Twitter tweet with the user and text of your choice. * **undertale:** Sends a text box from Undertale with the quote and character of your choice. diff --git a/commands/edit-image/emboss.js b/commands/edit-image/emboss.js new file mode 100644 index 00000000..653f4261 --- /dev/null +++ b/commands/edit-image/emboss.js @@ -0,0 +1,50 @@ +const Command = require('../../structures/Command'); +const gm = require('gm').subClass({ imageMagick: true }); +const request = require('node-superfetch'); + +module.exports = class EmbossCommand extends Command { + constructor(client) { + super(client, { + name: 'emboss', + group: 'edit-image', + memberName: 'emboss', + description: 'Draws an image or a user\'s avatar but embossed.', + throttling: { + usages: 1, + duration: 60 + }, + clientPermissions: ['ATTACH_FILES'], + args: [ + { + key: 'image', + prompt: 'What image would you like to edit?', + type: 'image', + default: msg => msg.author.displayAvatarURL({ format: 'png', size: 512 }) + } + ] + }); + } + + async run(msg, { image }) { + try { + const { body } = await request.get(image); + const magik = gm(body); + magik.emboss(); + magik.setFormat('png'); + const attachment = await this.toBuffer(magik); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'emboss.png' }] }); + } catch (err) { + return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); + } + } + + toBuffer(magik) { + return new Promise((res, rej) => { + magik.toBuffer((err, buffer) => { + if (err) return rej(err); + return res(buffer); + }); + }); + } +}; diff --git a/commands/edit-image/implode.js b/commands/edit-image/implode.js new file mode 100644 index 00000000..0634c312 --- /dev/null +++ b/commands/edit-image/implode.js @@ -0,0 +1,57 @@ +const Command = require('../../structures/Command'); +const gm = require('gm').subClass({ imageMagick: true }); +const request = require('node-superfetch'); + +module.exports = class ImplodeCommand extends Command { + constructor(client) { + super(client, { + name: 'implode', + group: 'edit-image', + memberName: 'implode', + description: 'Draws an image or a user\'s avatar but imploded.', + throttling: { + usages: 1, + duration: 60 + }, + clientPermissions: ['ATTACH_FILES'], + args: [ + { + key: 'level', + prompt: 'What level would you like to use? From 1-100.', + type: 'integer', + min: 1, + max: 100 + }, + { + key: 'image', + prompt: 'What image would you like to edit?', + type: 'image', + default: msg => msg.author.displayAvatarURL({ format: 'png', size: 512 }) + } + ] + }); + } + + async run(msg, { level, image }) { + try { + const { body } = await request.get(image); + const magik = gm(body); + magik.implode(level / 100); + magik.setFormat('png'); + const attachment = await this.toBuffer(magik); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'implode.png' }] }); + } catch (err) { + return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); + } + } + + toBuffer(magik) { + return new Promise((res, rej) => { + magik.toBuffer((err, buffer) => { + if (err) return rej(err); + return res(buffer); + }); + }); + } +}; diff --git a/commands/edit-image/magik.js b/commands/edit-image/liquid-rescale.js similarity index 84% rename from commands/edit-image/magik.js rename to commands/edit-image/liquid-rescale.js index 6ea467bc..2260575a 100644 --- a/commands/edit-image/magik.js +++ b/commands/edit-image/liquid-rescale.js @@ -2,13 +2,13 @@ const Command = require('../../structures/Command'); const gm = require('gm').subClass({ imageMagick: true }); const request = require('node-superfetch'); -module.exports = class MagikCommand extends Command { +module.exports = class LiquidRescaleCommand extends Command { constructor(client) { super(client, { - name: 'magik', - aliases: ['magick', 'liquid-rescale'], + name: 'liquid-rescale', + aliases: ['magick', 'magik'], group: 'edit-image', - memberName: 'magik', + memberName: 'liquid-rescale', description: 'Draws an image or a user\'s avatar but with liquid rescale from ImageMagick.', throttling: { usages: 1, @@ -36,7 +36,7 @@ module.exports = class MagikCommand extends Command { magik.setFormat('png'); const attachment = await this.toBuffer(magik); if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); - return msg.say({ files: [{ attachment, name: 'magik.png' }] }); + return msg.say({ files: [{ attachment, name: 'liquid-rescale.png' }] }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/edit-image/noise.js b/commands/edit-image/noise.js new file mode 100644 index 00000000..b1a86ae5 --- /dev/null +++ b/commands/edit-image/noise.js @@ -0,0 +1,60 @@ +const Command = require('../../structures/Command'); +const gm = require('gm').subClass({ imageMagick: true }); +const request = require('node-superfetch'); +const { list } = require('../../util/Util'); +const types = ['uniform', 'gaussian', 'multiplicative', 'impulse', 'laplacian', 'poisson']; + +module.exports = class NoiseCommand extends Command { + constructor(client) { + super(client, { + name: 'noise', + group: 'edit-image', + memberName: 'noise', + description: 'Draws an image or a user\'s avatar but with noise.', + details: `**Types:** ${types.join(', ')}`, + throttling: { + usages: 1, + duration: 60 + }, + clientPermissions: ['ATTACH_FILES'], + args: [ + { + key: 'type', + prompt: `What type of noise would you like to add? Either ${list(types, 'or')}.`, + type: 'string', + oneOf: types, + default: 'poisson' + }, + { + key: 'image', + prompt: 'What image would you like to edit?', + type: 'image', + default: msg => msg.author.displayAvatarURL({ format: 'png', size: 512 }) + } + ] + }); + } + + async run(msg, { type, image }) { + try { + const { body } = await request.get(image); + const magik = gm(body); + magik.noise(type); + magik.setFormat('png'); + const attachment = await this.toBuffer(magik); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'noise.png' }] }); + } catch (err) { + return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); + } + } + + toBuffer(magik) { + return new Promise((res, rej) => { + magik.toBuffer((err, buffer) => { + if (err) return rej(err); + return res(buffer); + }); + }); + } +}; diff --git a/commands/edit-image/oil-painting.js b/commands/edit-image/oil-painting.js new file mode 100644 index 00000000..1a97c173 --- /dev/null +++ b/commands/edit-image/oil-painting.js @@ -0,0 +1,51 @@ +const Command = require('../../structures/Command'); +const gm = require('gm').subClass({ imageMagick: true }); +const request = require('node-superfetch'); + +module.exports = class OilPaintingCommand extends Command { + constructor(client) { + super(client, { + name: 'oil-painting', + aliases: ['oil', 'paint', 'painting'], + group: 'edit-image', + memberName: 'noise', + description: 'Draws an image or a user\'s avatar but with oil paints.', + throttling: { + usages: 1, + duration: 60 + }, + clientPermissions: ['ATTACH_FILES'], + args: [ + { + key: 'image', + prompt: 'What image would you like to edit?', + type: 'image', + default: msg => msg.author.displayAvatarURL({ format: 'png', size: 512 }) + } + ] + }); + } + + async run(msg, { image }) { + try { + const { body } = await request.get(image); + const magik = gm(body); + magik.paint(5); + magik.setFormat('png'); + const attachment = await this.toBuffer(magik); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'old-painting.png' }] }); + } catch (err) { + return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); + } + } + + toBuffer(magik) { + return new Promise((res, rej) => { + magik.toBuffer((err, buffer) => { + if (err) return rej(err); + return res(buffer); + }); + }); + } +}; diff --git a/commands/edit-image/swirl.js b/commands/edit-image/swirl.js new file mode 100644 index 00000000..ec831b35 --- /dev/null +++ b/commands/edit-image/swirl.js @@ -0,0 +1,57 @@ +const Command = require('../../structures/Command'); +const gm = require('gm').subClass({ imageMagick: true }); +const request = require('node-superfetch'); + +module.exports = class SwirlCommand extends Command { + constructor(client) { + super(client, { + name: 'swirl', + group: 'edit-image', + memberName: 'swirl', + description: 'Draws an image or a user\'s avatar but swirled.', + throttling: { + usages: 1, + duration: 60 + }, + clientPermissions: ['ATTACH_FILES'], + args: [ + { + key: 'degrees', + prompt: 'What degrees would you like to use? From 1-360.', + type: 'integer', + min: 1, + max: 360 + }, + { + key: 'image', + prompt: 'What image would you like to edit?', + type: 'image', + default: msg => msg.author.displayAvatarURL({ format: 'png', size: 512 }) + } + ] + }); + } + + async run(msg, { degrees, image }) { + try { + const { body } = await request.get(image); + const magik = gm(body); + magik.swirl(degrees); + magik.setFormat('png'); + const attachment = await this.toBuffer(magik); + if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.'); + return msg.say({ files: [{ attachment, name: 'swirl.png' }] }); + } catch (err) { + return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); + } + } + + toBuffer(magik) { + return new Promise((res, rej) => { + magik.toBuffer((err, buffer) => { + if (err) return rej(err); + return res(buffer); + }); + }); + } +}; diff --git a/package.json b/package.json index 2e79b860..93c9e446 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiao", - "version": "119.3.1", + "version": "119.4.0", "description": "Your personal server companion.", "main": "Xiao.js", "scripts": {