illustrator.js
Version:
JavaScript image processing library
85 lines (84 loc) • 3.43 kB
JavaScript
;
var _ConvolutionTool_instances, _ConvolutionTool_convoluteInternal;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConvolutionTool = void 0;
const tslib_1 = require("tslib");
const ToolBox_1 = require("../base/ToolBox");
class ConvolutionTool extends ToolBox_1.ToolBox {
constructor() {
super(...arguments);
_ConvolutionTool_instances.add(this);
}
convolute(options) {
this.history.push(async (ctx) => {
options.iterations ?? (options.iterations = 1);
if (options.iterations < 1 || !Number.isFinite(options.iterations))
options.iterations = 1;
for (let i = 0; i < options.iterations; i++) {
tslib_1.__classPrivateFieldGet(this, _ConvolutionTool_instances, "m", _ConvolutionTool_convoluteInternal).call(this, {
ctx,
opaque: options.opaque ?? true,
sx: options.sx ?? 0,
sy: options.sy ?? 0,
matrix: options.matrix,
// not required here
iterations: 0
});
}
});
return this;
}
get matrices() {
return {
Identify: [0, 0, 0, 0, 1, 0, 0, 0, 0],
Ridge: [-1, -1, -1 - 1, 8, -1, -1, -1, -1],
Sharpen: [0, -1, 0, -1, 5, -1, 0, -1, 0],
Blur: [1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9],
Edge: [0, -1, 0, -1, 4, -1, 0, -1, 0]
};
}
}
exports.ConvolutionTool = ConvolutionTool;
_ConvolutionTool_instances = new WeakSet(), _ConvolutionTool_convoluteInternal = function _ConvolutionTool_convoluteInternal(options) {
const side = Math.round(Math.sqrt(options.matrix.length));
const halfSide = Math.floor(side / 2);
const pixels = options.ctx.getImageData(options.sx, options.sy, options.ctx.canvas.width, options.ctx.canvas.height);
const src = pixels.data;
const sw = pixels.width;
const sh = pixels.height;
const w = sw;
const h = sh;
const output = options.ctx.getImageData(options.sx, options.sy, options.ctx.canvas.width, options.ctx.canvas.height);
const dst = output.data;
const alphaFac = options.opaque ? 1 : 0;
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
const sy = y;
const sx = x;
const dstOff = (y * w + x) * 4;
let r = 0;
let g = 0;
let b = 0;
let a = 0;
for (let cy = 0; cy < side; cy++) {
for (let cx = 0; cx < side; cx++) {
const scy = sy + cy - halfSide;
const scx = sx + cx - halfSide;
if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) {
const srcOff = (scy * sw + scx) * 4;
const wt = options.matrix[cy * side + cx];
r += src[srcOff] * wt;
g += src[srcOff + 1] * wt;
b += src[srcOff + 2] * wt;
a += src[srcOff + 3] * wt;
}
}
}
dst[dstOff] = r;
dst[dstOff + 1] = g;
dst[dstOff + 2] = b;
dst[dstOff + 3] = a + alphaFac * (255 - a);
}
}
options.ctx.putImageData(output, options.sx, options.sy);
};