Skip to content

Commit

Permalink
Merge branch 'j433866-image-operations'
Browse files Browse the repository at this point in the history
  • Loading branch information
n1474335 committed Mar 9, 2019
2 parents d2d30bf + e10d4bf commit 45c1c23
Show file tree
Hide file tree
Showing 18 changed files with 1,523 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/core/Ingredient.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class Ingredient {
this.toggleValues = [];
this.target = null;
this.defaultIndex = 0;
this.min = null;
this.max = null;
this.step = 1;

if (ingredientConfig) {
this._parseConfig(ingredientConfig);
Expand All @@ -50,6 +53,9 @@ class Ingredient {
this.toggleValues = ingredientConfig.toggleValues;
this.target = typeof ingredientConfig.target !== "undefined" ? ingredientConfig.target : null;
this.defaultIndex = typeof ingredientConfig.defaultIndex !== "undefined" ? ingredientConfig.defaultIndex : 0;
this.min = ingredientConfig.min;
this.max = ingredientConfig.max;
this.step = ingredientConfig.step;
}


Expand Down
3 changes: 3 additions & 0 deletions src/core/Operation.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ class Operation {
if (ing.disabled) conf.disabled = ing.disabled;
if (ing.target) conf.target = ing.target;
if (ing.defaultIndex) conf.defaultIndex = ing.defaultIndex;
if (typeof ing.min === "number") conf.min = ing.min;
if (typeof ing.max === "number") conf.max = ing.max;
if (ing.step) conf.step = ing.step;
return conf;
});
}
Expand Down
15 changes: 14 additions & 1 deletion src/core/config/Categories.json
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,20 @@
"Play Media",
"Remove EXIF",
"Extract EXIF",
"Split Colour Channels"
"Split Colour Channels",
"Rotate Image",
"Resize Image",
"Blur Image",
"Dither Image",
"Invert Image",
"Flip Image",
"Crop Image",
"Image Brightness / Contrast",
"Image Opacity",
"Image Filter",
"Contain Image",
"Cover Image",
"Image Hue/Saturation/Lightness"
]
},
{
Expand Down
102 changes: 102 additions & 0 deletions src/core/operations/BlurImage.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
* @author j433866 [j433866@gmail.com]
* @copyright Crown Copyright 2019
* @license Apache-2.0
*/

import Operation from "../Operation";
import OperationError from "../errors/OperationError";
import { isImage } from "../lib/FileType";
import { toBase64 } from "../lib/Base64";
import jimp from "jimp";

/**
* Blur Image operation
*/
class BlurImage extends Operation {

/**
* BlurImage constructor
*/
constructor() {
super();

this.name = "Blur Image";
this.module = "Image";
this.description = "Applies a blur effect to the image.<br><br>Gaussian blur is much slower than fast blur, but produces better results.";
this.infoURL = "https://wikipedia.org/wiki/Gaussian_blur";
this.inputType = "byteArray";
this.outputType = "byteArray";
this.presentType = "html";
this.args = [
{
name: "Amount",
type: "number",
value: 5,
min: 1
},
{
name: "Type",
type: "option",
value: ["Fast", "Gaussian"]
}
];
}

/**
* @param {byteArray} input
* @param {Object[]} args
* @returns {byteArray}
*/
async run(input, args) {
const [blurAmount, blurType] = args;

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 "";

const type = isImage(data);
if (!type) {
throw new OperationError("Invalid file type.");
}

return `<img src="data:${type};base64,${toBase64(data)}">`;
}

}

export default BlurImage;
143 changes: 143 additions & 0 deletions src/core/operations/ContainImage.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/**
* @author j433866 [j433866@gmail.com]
* @copyright Crown Copyright 2019
* @license Apache-2.0
*/

import Operation from "../Operation";
import OperationError from "../errors/OperationError";
import { isImage } from "../lib/FileType";
import { toBase64 } from "../lib/Base64.mjs";
import jimp from "jimp";

/**
* Contain Image operation
*/
class ContainImage extends Operation {

/**
* ContainImage constructor
*/
constructor() {
super();

this.name = "Contain Image";
this.module = "Image";
this.description = "Scales an image to the specified width and height, maintaining the aspect ratio. The image may be letterboxed.";
this.infoURL = "";
this.inputType = "byteArray";
this.outputType = "byteArray";
this.presentType = "html";
this.args = [
{
name: "Width",
type: "number",
value: 100,
min: 1
},
{
name: "Height",
type: "number",
value: 100,
min: 1
},
{
name: "Horizontal align",
type: "option",
value: [
"Left",
"Center",
"Right"
],
defaultIndex: 1
},
{
name: "Vertical align",
type: "option",
value: [
"Top",
"Middle",
"Bottom"
],
defaultIndex: 1
},
{
name: "Resizing algorithm",
type: "option",
value: [
"Nearest Neighbour",
"Bilinear",
"Bicubic",
"Hermite",
"Bezier"
],
defaultIndex: 1
}
];
}

/**
* @param {byteArray} input
* @param {Object[]} args
* @returns {byteArray}
*/
async run(input, args) {
const [width, height, hAlign, vAlign, alg] = args;

const resizeMap = {
"Nearest Neighbour": jimp.RESIZE_NEAREST_NEIGHBOR,
"Bilinear": jimp.RESIZE_BILINEAR,
"Bicubic": jimp.RESIZE_BICUBIC,
"Hermite": jimp.RESIZE_HERMITE,
"Bezier": jimp.RESIZE_BEZIER
};

const alignMap = {
"Left": jimp.HORIZONTAL_ALIGN_LEFT,
"Center": jimp.HORIZONTAL_ALIGN_CENTER,
"Right": jimp.HORIZONTAL_ALIGN_RIGHT,
"Top": jimp.VERTICAL_ALIGN_TOP,
"Middle": jimp.VERTICAL_ALIGN_MIDDLE,
"Bottom": jimp.VERTICAL_ALIGN_BOTTOM
};

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("Containing image...");
image.contain(width, height, alignMap[hAlign] | alignMap[vAlign], resizeMap[alg]);
const imageBuffer = await image.getBufferAsync(jimp.AUTO);
return [...imageBuffer];
} catch (err) {
throw new OperationError(`Error containing image. (${err})`);
}
}

/**
* Displays the contained image using HTML for web apps
* @param {byteArray} data
* @returns {html}
*/
present(data) {
if (!data.length) return "";

const type = isImage(data);
if (!type) {
throw new OperationError("Invalid file type.");
}

return `<img src="data:${type};base64,${toBase64(data)}">`;
}

}

export default ContainImage;
Loading

0 comments on commit 45c1c23

Please sign in to comment.