image-in-browser
Version:
Package for encoding / decoding images, transforming images, applying filters, drawing primitives on images on the client side (no need for server Node.js)
91 lines • 3.19 kB
JavaScript
import { Channel } from '../color/channel.js';
import { ArrayUtils } from '../common/array-utils.js';
import { MathUtils } from '../common/math-utils.js';
export class SeparableKernel {
get length() {
return this._coefficients.length;
}
constructor(size) {
this._size = size;
this._coefficients = ArrayUtils.fill(2 * size + 1, 0);
}
reflect(max, x) {
if (x < 0) {
return -x;
}
if (x >= max) {
return max - (x - max) - 1;
}
return x;
}
applyCoefficientsLine(src, dst, y, width, horizontal, maskChannel, mask) {
const srcPixel = src.getPixelSafe(0, 0);
const dstPixel = dst.getPixelSafe(0, 0);
if (!srcPixel.isValid || !dstPixel.isValid) {
return;
}
for (let x = 0; x < width; x++) {
let r = 0;
let g = 0;
let b = 0;
let a = 0;
for (let j = -this._size, j2 = 0; j <= this._size; ++j, ++j2) {
const c = this._coefficients[j2];
const gr = this.reflect(width, x + j);
if (horizontal) {
srcPixel.setPosition(gr, y);
}
else {
srcPixel.setPosition(y, gr);
}
r += c * srcPixel.r;
g += c * srcPixel.g;
b += c * srcPixel.b;
a += c * srcPixel.a;
}
if (horizontal) {
dstPixel.setPosition(x, y);
}
else {
dstPixel.setPosition(y, x);
}
const msk = mask === null || mask === void 0 ? void 0 : mask.getPixel(dstPixel.x, dstPixel.y).getChannelNormalized(maskChannel);
if (msk === undefined) {
dstPixel.setRgba(r, g, b, a);
}
else {
dstPixel.r = MathUtils.mix(dstPixel.r, r, msk);
dstPixel.g = MathUtils.mix(dstPixel.g, g, msk);
dstPixel.b = MathUtils.mix(dstPixel.b, b, msk);
dstPixel.a = MathUtils.mix(dstPixel.a, a, msk);
}
}
}
getCoefficient(index) {
return this._coefficients[index];
}
setCoefficient(index, c) {
this._coefficients[index] = c;
}
apply(opt) {
var _a, _b;
const horizontal = (_a = opt.horizontal) !== null && _a !== void 0 ? _a : true;
const maskChannel = (_b = opt.maskChannel) !== null && _b !== void 0 ? _b : Channel.luminance;
if (horizontal) {
for (let y = 0; y < opt.src.height; ++y) {
this.applyCoefficientsLine(opt.src, opt.dst, y, opt.src.width, horizontal, maskChannel, opt.mask);
}
}
else {
for (let x = 0; x < opt.src.width; ++x) {
this.applyCoefficientsLine(opt.src, opt.dst, x, opt.src.height, horizontal, maskChannel, opt.mask);
}
}
}
scaleCoefficients(s) {
for (let i = 0; i < this._coefficients.length; ++i) {
this._coefficients[i] *= s;
}
}
}
//# sourceMappingURL=separable-kernel.js.map