const hasard = require('hasard');
const AbstractAugmenter = require('./abstract');
/**
* Left - Top - Right - Bottom array
* If Size 2, then we consider Left = Right and Top = Bottom
* If Number, then Left = Top = Right = Bottom = Number
* @typedef {Number | Array.<Number> | Hasard.<Number> | Hasard.<Array.<Number>>} ArraylRTB
*/
/**
* Crop the image
* @param {Object} opts options, if number of array, it is considered as size
* @param {ArraylRTB} opts.percent percent of cropping to do
* @param {ArraylRTB} opts.size value of cropping to do
* @example
// Simple usage, crop by 10px, on every side
ia.crop(10);
* @example
//Simple usage with random variable crop by 10% to 30%
ia.crop({percent : h.number(0.1, 0.3)});
* @example
//Crop by 10% on left, 20% on top, to 30% on the right, 10% on the bottom
ia.crop({percent: [0.1, 0.2, 0.3, 0.1]});
*/
class CropAugmenter extends AbstractAugmenter {
constructor(opts, ia) {
let o;
if (typeof (opts) === 'number' || Array.isArray(opts) || hasard.isHasard(opts)) {
o = {size: opts};
} else {
o = opts;
}
super(o, ia);
const {percent, size} = o;
if (hasard.isHasard(size) || typeof (size) === 'number' || Array.isArray(size)) {
this.size = this.toSize4(size);
} else {
this.percent = this.toSize4(percent);
}
}
buildParams({width, height}) {
return new hasard.Object({
size: this.size || hasard.fn(p => [
Math.round(width * p[0]),
Math.round(height * p[1]),
Math.round(width * p[2]),
Math.round(height * p[3])
])(this.percent)
});
}
checkParams({size}) {
size.forEach(p => {
if (p < 0) {
throw (new Error('only positive value allowed in crop for percent'));
}
});
}
getRect({width, height, params}) {
const size = params.size.concat();
return {
x: size[0],
y: size[1],
w: width - size[2] - size[0],
h: height - size[3] - size[1]
};
}
augmentImage({image, width, height}, params) {
const rect = this.getRect({width, height, params});
if (rect.w <= 0 || rect.h <= 0) {
throw (new Error(`Cannot crop by ${JSON.stringify(params)}`));
}
const res = this.backend.crop(image, rect);
return res;
}
augmentPointsOnImage({points, width, height}, params) {
const rect = this.getRect({width, height, params});
const origin = this.backend.point(rect.x, rect.y);
return points.map(p => p.sub(origin));
}
}
module.exports = CropAugmenter;