如何用Jimp实现图片遮罩?解决黑白输出异常问题
Jimp遮罩图片后输出黑白效果的解决方法
问题描述
我希望使用Jimp将遮罩用的彩色图案图遮罩到彩色底图上,预期得到色彩保留的遮罩合成效果,但执行代码后生成的图片却是黑白效果。
原代码
const Jimp = require('jimp'); module.exports = async d => { const data = d.util.aoiFunc(d); const [c = ""] = data.inside.splits; const plate = await Jimp.read('你的底图路径'); const card = await Jimp.read('你的遮罩图路径'); plate.mask(card, 0, 0); await plate.writeAsync(`path/output.png`); return { code: d.util.setCode(data) }; };
问题原因
Jimp的mask()方法默认会将遮罩图像转换为灰度图,用像素的灰度值来控制底图的透明度,因此最终输出会丢失底图的色彩,呈现黑白效果。
解决方案
改用composite()方法并指定Jimp.BLEND_DEST_IN混合模式,该模式可以保留底图的原始色彩,同时根据遮罩图的透明区域裁切显示范围。如果遮罩图本身没有Alpha通道,需要先将非图案区域(比如白色背景)设置为透明。
修改后的代码
const Jimp = require('jimp'); module.exports = async d => { const data = d.util.aoiFunc(d); const [c = ""] = data.inside.splits; const plate = await Jimp.read('你的底图路径'); const card = await Jimp.read('你的遮罩图路径'); // 处理遮罩图:将白色背景转为透明(若遮罩图已有Alpha通道可跳过此步骤) await card.scan(0, 0, card.bitmap.width, card.bitmap.height, function (x, y, idx) { const red = this.bitmap.data[idx + 0]; const green = this.bitmap.data[idx + 1]; const blue = this.bitmap.data[idx + 2]; // 阈值可根据遮罩图实际颜色调整 if (red > 240 && green > 240 && blue > 240) { this.bitmap.data[idx + 3] = 0; // 设置Alpha通道为0(完全透明) } }); // 使用DEST_IN混合模式合成,保留底图色彩并按遮罩形状裁切 plate.composite(card, 0, 0, { mode: Jimp.BLEND_DEST_IN }); await plate.writeAsync(`path/output.png`); return { code: d.util.setCode(data) }; };
代码说明
Jimp.BLEND_DEST_IN:仅保留底图中与遮罩图不透明区域重叠的部分,完全保留底图的色彩信息。- 遮罩图透明化处理:针对无Alpha通道的遮罩图,通过扫描像素将白色背景转为透明,确保裁切逻辑正确;若遮罩图本身已带透明通道,可直接删除该扫描步骤。
内容的提问来源于stack exchange,提问作者Ayaka Kamisato
相关产品推荐
相关产品推荐

