image-js
Version:
Image processing and manipulation in JavaScript
95 lines (85 loc) • 2.49 kB
text/typescript
import { Image } from '../Image.js';
import type { Point } from '../utils/geometry/points.js';
import { checkPointIsInteger } from '../utils/validators/checkPointIsInteger.js';
import checkProcessable from '../utils/validators/checkProcessable.js';
export interface CropOptions {
/**
* Origin of the crop relative to a parent image (top-left corner).
* @default `{row: 0, column: 0}`
*/
origin?: Point;
/**
* Specify the width of the cropped image.
* @default `image.width`
*/
width?: number;
/**
* Specify the width of the cropped image.
* @default `image.height`
*/
height?: number;
}
/**
* Crop the input image to a desired size.
* @param image - Image to crop.
* @param [options] - Crop options.
* @returns The new cropped image.
* @example
* var cropped = image.crop({
* row:20,
* column:100
* });
*/
export function crop(image: Image, options: CropOptions = {}) {
const {
origin = { row: 0, column: 0 },
width = image.width - origin.column,
height = image.height - origin.row,
} = options;
const { column, row } = origin;
checkProcessable(image, {
bitDepth: [8, 16],
});
checkPointIsInteger(origin, 'Origin');
if (!Number.isInteger(width) || !Number.isInteger(height)) {
throw new RangeError(
`Width and height (width:${width}; height:${height}) must be integers`,
);
}
if (row > image.height - 1 || column > image.width - 1) {
throw new RangeError(
`Origin (row:${row}, column:${column}) out of range (${
image.width - 1
}; ${image.height - 1})`,
);
}
if (width <= 0 || height <= 0) {
throw new RangeError(
`Width and height (width:${width}; height:${height}) must be positive numbers`,
);
}
if (row < 0 || column < 0) {
throw new RangeError(
`Row and column (row:${row}, column:${column}) must be positive numbers`,
);
}
if (width > image.width - column || height > image.height - row) {
throw new RangeError(
`Size is out of range (row:${row}, column:${column}, width:${width}, height:${height})`,
);
}
const newImage = Image.createFrom(image, {
width,
height,
});
for (let currentRow = 0; currentRow < height; currentRow++) {
for (let currentColumn = 0; currentColumn < width; currentColumn++) {
newImage.setPixel(
currentColumn,
currentRow,
image.getPixel(column + currentColumn, row + currentRow),
);
}
}
return newImage;
}