图像增强辅助类
<pre><code class="language-javascript">/**
* 图像处理工具类
*/
export class IMAGEHANDLE {
constructor() {
this.createTime = Date.now();
}
/**
* 获取原始图像颜色值
* @param {*} x
* @param {*} y
* @param {*} srcData
* @param {*} srcWidth
* @returns
*/
getPixel(x, y, srcData, srcWidth) {
const index = (y * srcWidth + x) * 4;
return {
r: srcData[index],
g: srcData[index + 1],
b: srcData[index + 2],
a: srcData[index + 3]
};
}
/**
*
* @param {*} x
* @param {*} y
* @param {*} srcData
* @param {*} srcWidth
* @param {*} srcHeight
* @returns
*/
getPixelSafe(x, y, srcData, srcWidth, srcHeight) {
x = Math.min(Math.max(x, 0), srcWidth - 1);
y = Math.min(Math.max(y, 0), srcHeight - 1);
const index = (y * srcWidth + x) * 4;
return {
r: srcData[index],
g: srcData[index + 1],
b: srcData[index + 2],
a: srcData[index + 3]
};
}
/**
* 双三次插值算法
* @param {*} srcImageData
* @param {*} newWidth
* @param {*} newHeight
* @returns
*/
bicubicInterpolation(srcImageData, newWidth, newHeight) {
const srcWidth = srcImageData.width;
const srcHeight = srcImageData.height;
const srcData = srcImageData.data;
const dstData = new Uint8ClampedArray(newWidth * newHeight * 4);
const scaleX = srcWidth / newWidth;
const scaleY = srcHeight / newHeight;
for (let y = 0; y &lt; newHeight; y++) {
for (let x = 0; x &lt; newWidth; x++) {
const gx = Math.min(srcWidth - 1, Math.max(0, x * scaleX));
const gy = Math.min(srcHeight - 1, Math.max(0, y * scaleY));
const gxi = Math.floor(gx);
const gyi = Math.floor(gy);
const dx = gx - gxi;
const dy = gy - gyi;
const weightsX = [this.cubic(dx + 1 - 0), this.cubic(dx + 1 - 1), this.cubic(dx + 1 - 2), this.cubic(dx + 1 - 3)];
const weightsY = [this.cubic(dy + 1 - 0), this.cubic(dy + 1 - 1), this.cubic(dy + 1 - 2), this.cubic(dy + 1 - 3)];
const pixel = [0, 0, 0, 0];
for (let i = 0; i &lt; 4; i++) {
const gxx = gxi - 1 + i;
const wx = weightsX[i];
for (let j = 0; j &lt; 4; j++) {
const gyy = gyi - 1 + j;
const wy = weightsY[j];
const weight = wx * wy;
const srcPixel = this.getPixelSafe(gxx, gyy, srcData, srcWidth, srcHeight);
pixel[0] += srcPixel.r * weight;
pixel[1] += srcPixel.g * weight;
pixel[2] += srcPixel.b * weight;
pixel[3] += srcPixel.a * weight;
}
}
const index = (y * newWidth + x) * 4;
dstData[index] = this.clamp(pixel[0], 0, 255);
dstData[index + 1] = this.clamp(pixel[1], 0, 255);
dstData[index + 2] = this.clamp(pixel[2], 0, 255);
dstData[index + 3] = this.clamp(pixel[3], 0, 255);
}
}
return new ImageData(dstData, newWidth, newHeight);
}
/**
* 计算权重算法
* @param {*} t
* @returns
*/
cubic(t) {
const a = -0.5;
const at = Math.abs(t);
if (at &lt;= 1) {
return ((a + 2) * at - (a + 3)) * at * at + 1;
} else if (at &lt; 2) {
return ((a * at - 5 * a) * at + 8 * a) * at - 4 * a;
}
return 0;
}
// Clamp function for value within [min, max]
clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
}</code></pre>