Tidied up image manipulation ops

This commit is contained in:
n1474335 2019-03-09 07:23:11 +00:00
parent 369b640408
commit e10d4bf45c
14 changed files with 143 additions and 236 deletions

View File

@ -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;
}
const imageBuffer = await image.getBufferAsync(jimp.AUTO);
return [...imageBuffer];
} catch (err) {
throw new OperationError(`Error blurring 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 {
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;
}
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)}">`;
}
}

View File

@ -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)}">`;
}
}

View File

@ -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)}">`;
}
}

View File

@ -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)}">`;
}
}

View File

@ -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)}">`;
}
}

View File

@ -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)}">`;
}
}

View File

@ -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)}">`;
}
}

View File

@ -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)}">`;
}
}

View File

@ -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)}">`;
}
}

View File

@ -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)}">`;
}
}

View File

@ -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)}">`;
}
}

View File

@ -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)}">`;
}
}

View File

@ -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)}">`;
}
}

View File

@ -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)}">`;
}
}