Explorar o código

Tidied up image manipulation ops

n1474335 %!s(int64=6) %!d(string=hai) anos
pai
achega
e10d4bf45c

+ 31 - 36
src/core/operations/BlurImage.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64";
 import jimp from "jimp";
 
@@ -30,13 +30,13 @@ class BlurImage extends Operation {
         this.presentType = "html";
         this.args = [
             {
-                name: "Blur Amount",
+                name: "Amount",
                 type: "number",
                 value: 5,
                 min: 1
             },
             {
-                name: "Blur Type",
+                name: "Type",
                 type: "option",
                 value: ["Fast", "Gaussian"]
             }
@@ -50,56 +50,51 @@ class BlurImage extends Operation {
      */
     async run(input, args) {
         const [blurAmount, blurType] = args;
-        const type = Magic.magicFileType(input);
 
-        if (type && type.mime.indexOf("image") === 0){
-            let image;
-            try {
-                image = await jimp.read(Buffer.from(input));
-            } catch (err) {
-                throw new OperationError(`Error loading image. (${err})`);
-            }
-            try {
-                switch (blurType){
-                    case "Fast":
-                        image.blur(blurAmount);
-                        break;
-                    case "Gaussian":
-                        if (ENVIRONMENT_IS_WORKER())
-                            self.sendStatusMessage("Gaussian blurring image. This will take a while...");
-                        image.gaussian(blurAmount);
-                        break;
-                }
+        if (!isImage(input)) {
+            throw new OperationError("Invalid file type.");
+        }
 
-                const imageBuffer = await image.getBufferAsync(jimp.AUTO);
-                return [...imageBuffer];
-            } catch (err) {
-                throw new OperationError(`Error blurring image. (${err})`);
+        let image;
+        try {
+            image = await jimp.read(Buffer.from(input));
+        } catch (err) {
+            throw new OperationError(`Error loading image. (${err})`);
+        }
+        try {
+            switch (blurType){
+                case "Fast":
+                    image.blur(blurAmount);
+                    break;
+                case "Gaussian":
+                    if (ENVIRONMENT_IS_WORKER())
+                        self.sendStatusMessage("Gaussian blurring image. This may take a while...");
+                    image.gaussian(blurAmount);
+                    break;
             }
-        } else {
-            throw new OperationError("Invalid file type.");
+
+            const imageBuffer = await image.getBufferAsync(jimp.AUTO);
+            return [...imageBuffer];
+        } catch (err) {
+            throw new OperationError(`Error blurring image. (${err})`);
         }
     }
 
     /**
      * Displays the blurred image using HTML for web apps
+     *
      * @param {byteArray} data
      * @returns {html}
      */
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
+        const type = isImage(data);
+        if (!type) {
             throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
-
-        return "<img src='" + dataURI + "'>";
 
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 
 }

+ 6 - 11
src/core/operations/ContainImage.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64.mjs";
 import jimp from "jimp";
 
@@ -83,7 +83,6 @@ class ContainImage extends Operation {
      */
     async run(input, args) {
         const [width, height, hAlign, vAlign, alg] = args;
-        const type = Magic.magicFileType(input);
 
         const resizeMap = {
             "Nearest Neighbour": jimp.RESIZE_NEAREST_NEIGHBOR,
@@ -102,7 +101,7 @@ class ContainImage extends Operation {
             "Bottom": jimp.VERTICAL_ALIGN_BOTTOM
         };
 
-        if (!type || type.mime.indexOf("image") !== 0){
+        if (!isImage(input)) {
             throw new OperationError("Invalid file type.");
         }
 
@@ -131,16 +130,12 @@ class ContainImage extends Operation {
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
-            throw new OperationError("Invalid file type");
+        const type = isImage(data);
+        if (!type) {
+            throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
 
-        return "<img src='" + dataURI + "'>";
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 
 }

+ 6 - 11
src/core/operations/CoverImage.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64.mjs";
 import jimp from "jimp";
 
@@ -83,7 +83,6 @@ class CoverImage extends Operation {
      */
     async run(input, args) {
         const [width, height, hAlign, vAlign, alg] = args;
-        const type = Magic.magicFileType(input);
 
         const resizeMap = {
             "Nearest Neighbour": jimp.RESIZE_NEAREST_NEIGHBOR,
@@ -102,7 +101,7 @@ class CoverImage extends Operation {
             "Bottom": jimp.VERTICAL_ALIGN_BOTTOM
         };
 
-        if (!type || type.mime.indexOf("image") !== 0){
+        if (!isImage(input)) {
             throw new OperationError("Invalid file type.");
         }
 
@@ -131,16 +130,12 @@ class CoverImage extends Operation {
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
-            throw new OperationError("Invalid file type");
+        const type = isImage(data);
+        if (!type) {
+            throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
 
-        return "<img src='" + dataURI + "'>";
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 
 }

+ 7 - 13
src/core/operations/CropImage.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64.mjs";
 import jimp from "jimp";
 
@@ -23,7 +23,7 @@ class CropImage extends Operation {
 
         this.name = "Crop Image";
         this.module = "Image";
-        this.description = "Crops an image to the specified region, or automatically crop edges.<br><br><b><u>Autocrop</u></b><br>Automatically crops same-colour borders from the image.<br><br><u>Autocrop tolerance</u><br>A percentage value for the tolerance of colour difference between pixels.<br><br><u>Only autocrop frames</u><br>Only crop real frames (all sides must have the same border)<br><br><u>Symmetric autocrop</u><br>Force autocrop to be symmetric (top/bottom and left/right are cropped by the same amount)<br><br><u>Autocrop keep border</u><br>The number of pixels of border to leave around the image.";
+        this.description = "Crops an image to the specified region, or automatically crops edges.<br><br><b><u>Autocrop</u></b><br>Automatically crops same-colour borders from the image.<br><br><u>Autocrop tolerance</u><br>A percentage value for the tolerance of colour difference between pixels.<br><br><u>Only autocrop frames</u><br>Only crop real frames (all sides must have the same border)<br><br><u>Symmetric autocrop</u><br>Force autocrop to be symmetric (top/bottom and left/right are cropped by the same amount)<br><br><u>Autocrop keep border</u><br>The number of pixels of border to leave around the image.";
         this.infoURL = "https://wikipedia.org/wiki/Cropping_(image)";
         this.inputType = "byteArray";
         this.outputType = "byteArray";
@@ -91,10 +91,8 @@ class CropImage extends Operation {
      * @returns {byteArray}
      */
     async run(input, args) {
-        // const [firstArg, secondArg] = args;
         const [xPos, yPos, width, height, autocrop, autoTolerance, autoFrames, autoSymmetric, autoBorder] = args;
-        const type = Magic.magicFileType(input);
-        if (!type || type.mime.indexOf("image") !== 0){
+        if (!isImage(input)) {
             throw new OperationError("Invalid file type.");
         }
 
@@ -133,16 +131,12 @@ class CropImage extends Operation {
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
-            throw new OperationError("Invalid file type");
+        const type = isImage(data);
+        if (!type) {
+            throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
 
-        return "<img src='" + dataURI + "'>";
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 
 }

+ 21 - 28
src/core/operations/DitherImage.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64";
 import jimp from "jimp";
 
@@ -37,27 +37,25 @@ class DitherImage extends Operation {
      * @returns {byteArray}
      */
     async run(input, args) {
-        const type = Magic.magicFileType(input);
-
-        if (type && type.mime.indexOf("image") === 0){
-            let image;
-            try {
-                image = await jimp.read(Buffer.from(input));
-            } catch (err) {
-                throw new OperationError(`Error loading image. (${err})`);
-            }
-            try {
-                if (ENVIRONMENT_IS_WORKER())
-                    self.sendStatusMessage("Applying dither to image...");
-                image.dither565();
-                const imageBuffer = await image.getBufferAsync(jimp.AUTO);
-                return [...imageBuffer];
-            } catch (err) {
-                throw new OperationError(`Error applying dither to image. (${err})`);
-            }
-        } else {
+        if (!isImage(input)) {
             throw new OperationError("Invalid file type.");
         }
+
+        let image;
+        try {
+            image = await jimp.read(Buffer.from(input));
+        } catch (err) {
+            throw new OperationError(`Error loading image. (${err})`);
+        }
+        try {
+            if (ENVIRONMENT_IS_WORKER())
+                self.sendStatusMessage("Applying dither to image...");
+            image.dither565();
+            const imageBuffer = await image.getBufferAsync(jimp.AUTO);
+            return [...imageBuffer];
+        } catch (err) {
+            throw new OperationError(`Error applying dither to image. (${err})`);
+        }
     }
 
     /**
@@ -68,17 +66,12 @@ class DitherImage extends Operation {
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
+        const type = isImage(data);
+        if (!type) {
             throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
-
-        return "<img src='" + dataURI + "'>";
 
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 
 }

+ 7 - 13
src/core/operations/FlipImage.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64";
 import jimp from "jimp";
 
@@ -27,10 +27,10 @@ class FlipImage extends Operation {
         this.infoURL = "";
         this.inputType = "byteArray";
         this.outputType = "byteArray";
-        this.presentType="html";
+        this.presentType = "html";
         this.args = [
             {
-                name: "Flip Axis",
+                name: "Axis",
                 type: "option",
                 value: ["Horizontal", "Vertical"]
             }
@@ -44,8 +44,7 @@ class FlipImage extends Operation {
      */
     async run(input, args) {
         const [flipAxis] = args;
-        const type = Magic.magicFileType(input);
-        if (!type || type.mime.indexOf("image") !== 0){
+        if (!isImage(input)) {
             throw new OperationError("Invalid input file type.");
         }
 
@@ -82,17 +81,12 @@ class FlipImage extends Operation {
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
+        const type = isImage(data);
+        if (!type) {
             throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
-
-        return "<img src='" + dataURI + "'>";
 
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 
 }

+ 8 - 13
src/core/operations/ImageBrightnessContrast.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64.mjs";
 import jimp from "jimp";
 
@@ -23,7 +23,7 @@ class ImageBrightnessContrast extends Operation {
 
         this.name = "Image Brightness / Contrast";
         this.module = "Image";
-        this.description = "Adjust the brightness and contrast of an image.";
+        this.description = "Adjust the brightness or contrast of an image.";
         this.infoURL = "";
         this.inputType = "byteArray";
         this.outputType = "byteArray";
@@ -53,8 +53,7 @@ class ImageBrightnessContrast extends Operation {
      */
     async run(input, args) {
         const [brightness, contrast] = args;
-        const type = Magic.magicFileType(input);
-        if (!type || type.mime.indexOf("image") !== 0){
+        if (!isImage(input)) {
             throw new OperationError("Invalid file type.");
         }
 
@@ -79,7 +78,7 @@ class ImageBrightnessContrast extends Operation {
             const imageBuffer = await image.getBufferAsync(jimp.AUTO);
             return [...imageBuffer];
         } catch (err) {
-            throw new OperationError(`Error adjusting image brightness / contrast. (${err})`);
+            throw new OperationError(`Error adjusting image brightness or contrast. (${err})`);
         }
     }
 
@@ -91,16 +90,12 @@ class ImageBrightnessContrast extends Operation {
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
-            throw new OperationError("Invalid file type");
+        const type = isImage(data);
+        if (!type) {
+            throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
 
-        return "<img src='" + dataURI + "'>";
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 
 }

+ 5 - 11
src/core/operations/ImageFilter.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64.mjs";
 import jimp from "jimp";
 
@@ -47,8 +47,7 @@ class ImageFilter extends Operation {
      */
     async run(input, args) {
         const [filterType] = args;
-        const type = Magic.magicFileType(input);
-        if (!type || type.mime.indexOf("image") !== 0){
+        if (!isImage(input)){
             throw new OperationError("Invalid file type.");
         }
 
@@ -82,17 +81,12 @@ class ImageFilter extends Operation {
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
+        const type = isImage(data);
+        if (!type) {
             throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
-
-        return "<img src='" + dataURI + "'>";
 
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 
 }

+ 6 - 11
src/core/operations/ImageHueSaturationLightness.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64.mjs";
 import jimp from "jimp";
 
@@ -60,9 +60,8 @@ class ImageHueSaturationLightness extends Operation {
      */
     async run(input, args) {
         const [hue, saturation, lightness] = args;
-        const type = Magic.magicFileType(input);
 
-        if (!type || type.mime.indexOf("image") !== 0){
+        if (!isImage(input)) {
             throw new OperationError("Invalid file type.");
         }
 
@@ -118,16 +117,12 @@ class ImageHueSaturationLightness extends Operation {
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
-            throw new OperationError("Invalid file type");
+        const type = isImage(data);
+        if (!type) {
+            throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
 
-        return "<img src='" + dataURI + "'>";
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 }
 

+ 6 - 11
src/core/operations/ImageOpacity.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64.mjs";
 import jimp from "jimp";
 
@@ -46,8 +46,7 @@ class ImageOpacity extends Operation {
      */
     async run(input, args) {
         const [opacity] = args;
-        const type = Magic.magicFileType(input);
-        if (!type || type.mime.indexOf("image") !== 0){
+        if (!isImage(input)) {
             throw new OperationError("Invalid file type.");
         }
 
@@ -77,16 +76,12 @@ class ImageOpacity extends Operation {
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
-            throw new OperationError("Invalid file type");
+        const type = isImage(data);
+        if (!type) {
+            throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
 
-        return "<img src='" + dataURI + "'>";
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 
 }

+ 5 - 11
src/core/operations/InvertImage.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64";
 import jimp from "jimp";
 
@@ -37,8 +37,7 @@ class InvertImage extends Operation {
      * @returns {byteArray}
      */
     async run(input, args) {
-        const type = Magic.magicFileType(input);
-        if (!type || type.mime.indexOf("image") !== 0) {
+        if (!isImage(input)) {
             throw new OperationError("Invalid input file format.");
         }
 
@@ -67,17 +66,12 @@ class InvertImage extends Operation {
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
+        const type = isImage(data);
+        if (!type) {
             throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
-
-        return "<img src='" + dataURI + "'>";
 
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 
 }

+ 6 - 27
src/core/operations/NormaliseImage.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64";
 import jimp from "jimp";
 
@@ -28,20 +28,7 @@ class NormaliseImage extends Operation {
         this.inputType = "byteArray";
         this.outputType = "byteArray";
         this.presentType=  "html";
-        this.args = [
-            /* Example arguments. See the project wiki for full details.
-            {
-                name: "First arg",
-                type: "string",
-                value: "Don't Panic"
-            },
-            {
-                name: "Second arg",
-                type: "number",
-                value: 42
-            }
-            */
-        ];
+        this.args = [];
     }
 
     /**
@@ -50,10 +37,7 @@ class NormaliseImage extends Operation {
      * @returns {byteArray}
      */
     async run(input, args) {
-        // const [firstArg, secondArg] = args;
-        const type = Magic.magicFileType(input);
-
-        if (!type || type.mime.indexOf("image") !== 0){
+        if (!isImage(input)) {
             throw new OperationError("Invalid file type.");
         }
 
@@ -73,17 +57,12 @@ class NormaliseImage extends Operation {
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
+        const type = isImage(data);
+        if (!type) {
             throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
-
-        return "<img src='" + dataURI + "'>";
 
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 
 }

+ 7 - 12
src/core/operations/ResizeImage.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64.mjs";
 import jimp from "jimp";
 
@@ -76,8 +76,7 @@ class ResizeImage extends Operation {
             height = args[1];
         const unit = args[2],
             aspect = args[3],
-            resizeAlg = args[4],
-            type = Magic.magicFileType(input);
+            resizeAlg = args[4];
 
         const resizeMap = {
             "Nearest Neighbour": jimp.RESIZE_NEAREST_NEIGHBOR,
@@ -87,7 +86,7 @@ class ResizeImage extends Operation {
             "Bezier": jimp.RESIZE_BEZIER
         };
 
-        if (!type || type.mime.indexOf("image") !== 0){
+        if (!isImage(input)) {
             throw new OperationError("Invalid file type.");
         }
 
@@ -126,16 +125,12 @@ class ResizeImage extends Operation {
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
-            throw new OperationError("Invalid file type");
+        const type = isImage(data);
+        if (!type) {
+            throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
 
-        return "<img src='" + dataURI + "'>";
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 
 }

+ 21 - 27
src/core/operations/RotateImage.mjs

@@ -6,7 +6,7 @@
 
 import Operation from "../Operation";
 import OperationError from "../errors/OperationError";
-import Magic from "../lib/Magic";
+import { isImage } from "../lib/FileType";
 import { toBase64 } from "../lib/Base64";
 import jimp from "jimp";
 
@@ -44,27 +44,26 @@ class RotateImage extends Operation {
      */
     async run(input, args) {
         const [degrees] = args;
-        const type = Magic.magicFileType(input);
 
-        if (type && type.mime.indexOf("image") === 0){
-            let image;
-            try {
-                image = await jimp.read(Buffer.from(input));
-            } catch (err) {
-                throw new OperationError(`Error loading image. (${err})`);
-            }
-            try {
-                if (ENVIRONMENT_IS_WORKER())
-                    self.sendStatusMessage("Rotating image...");
-                image.rotate(degrees);
-                const imageBuffer = await image.getBufferAsync(jimp.AUTO);
-                return [...imageBuffer];
-            } catch (err) {
-                throw new OperationError(`Error rotating image. (${err})`);
-            }
-        } else {
+        if (!isImage(input)) {
             throw new OperationError("Invalid file type.");
         }
+
+        let image;
+        try {
+            image = await jimp.read(Buffer.from(input));
+        } catch (err) {
+            throw new OperationError(`Error loading image. (${err})`);
+        }
+        try {
+            if (ENVIRONMENT_IS_WORKER())
+                self.sendStatusMessage("Rotating image...");
+            image.rotate(degrees);
+            const imageBuffer = await image.getBufferAsync(jimp.AUTO);
+            return [...imageBuffer];
+        } catch (err) {
+            throw new OperationError(`Error rotating image. (${err})`);
+        }
     }
 
     /**
@@ -75,17 +74,12 @@ class RotateImage extends Operation {
     present(data) {
         if (!data.length) return "";
 
-        let dataURI = "data:";
-        const type = Magic.magicFileType(data);
-        if (type && type.mime.indexOf("image") === 0){
-            dataURI += type.mime + ";";
-        } else {
+        const type = isImage(data);
+        if (!type) {
             throw new OperationError("Invalid file type.");
         }
-        dataURI += "base64," + toBase64(data);
-
-        return "<img src='" + dataURI + "'>";
 
+        return `<img src="data:${type};base64,${toBase64(data)}">`;
     }
 
 }