You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:18:22