You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Lab模式下Photoshop UXP插件如何用像素数据创建Lab填充层蒙版

解决方案:Lab模式下将Uint8Array像素转为填充层蒙版(Photoshop UXP插件)

首选方案:将像素数据转为选区,再生成蒙版

利用临时灰度通道承载像素数据,基于通道创建选区后复用你已验证的revealSelection流程,避开Lab色彩空间的适配问题:

步骤说明

  • 创建临时灰度Alpha通道,将maskData写入该通道(灰度通道无需适配Lab色彩空间)
  • 基于临时通道创建选区
  • 创建Lab填充层并通过选区生成蒙版
  • 删除临时通道

代码实现

async function createLabFillWithPixelMask(doc, bounds, maskData, width, height, labColor) {
  // 1. 创建临时灰度通道
  const tempChannel = await doc.channels.add();
  await tempChannel.changeMode("Grayscale");

  // 2. 将maskData写入临时通道
  await require('photoshop').imaging.putPixels({
    target: tempChannel,
    data: maskData,
    width: width,
    height: height,
    colorSpace: "Grayscale",
    components: 1,
    bytesPerComponent: 1
  });

  // 3. 基于临时通道创建选区
  await action.batchPlay([
    {
      _obj: "set",
      target: { _ref: "selection" },
      to: {
        _obj: "channel",
        _ref: "channel",
        _enum: "channel",
        _value: tempChannel.name
      }
    }
  ], { synchronousExecution: true });

  // 4. 创建Lab填充层+蒙版(复用已验证逻辑)
  await action.batchPlay([
    { 
      "_obj": "make", 
      "target": { "_ref": "contentLayer" },
      "using": { 
        "type": { 
          "_obj": "solidColorLayer",
          "color": { 
            "_obj": "labColor", 
            "luminance": labColor.l, 
            "a": labColor.a, 
            "b": labColor.b 
          } 
        } 
      } 
    },
    { 
      "_obj": "make", 
      "new": { "_class": "mask" },
      "using": { "_enum": "userMaskEnabled", "_value": "revealSelection" } 
    }
  ], { "synchronousExecution": true });

  // 5. 删除临时通道
  await tempChannel.delete();
}

// 调用示例
const doc = require('photoshop').app.activeDocument;
const bounds = { top: 0, left: 0, bottom: 200, right: 200 };
const width = 200;
const height = 200;
const maskData = new Uint8Array(width * height);
// 填充示例数据:中心区域可见,其余遮挡
for (let y = 0; y < height; y++) {
  for (let x = 0; x < width; x++) {
    const dist = Math.sqrt(Math.pow(x - width/2, 2) + Math.pow(y - height/2, 2));
    maskData[y * width + x] = dist < 50 ? 255 : 0;
  }
}
const labColor = { l: 50, a: 80, b: 70 };
createLabFillWithPixelMask(doc, bounds, maskData, width, height, labColor);

替代方案:直接写入填充层蒙版(绕过target sheet错误)

填充层的蒙版本质是关联的Alpha通道,可通过batchPlay直接定位蒙版通道并写入像素数据:

代码实现

async function createLabFillAndWriteMask(doc, bounds, maskData, width, height, labColor) {
  // 1. 创建带蒙版的Lab填充层
  const [fillLayer] = await action.batchPlay([
    { 
      "_obj": "make", 
      "target": { "_ref": "contentLayer" },
      "using": { 
        "type": { 
          "_obj": "solidColorLayer",
          "color": { 
            "_obj": "labColor", 
            "luminance": labColor.l, 
            "a": labColor.a, 
            "b": labColor.b 
          } 
        },
        "mask": {
          "_obj": "mask",
          "userMaskEnabled": true
        }
      } 
    }
  ], { "synchronousExecution": true, "modalBehavior": "fail" });

  // 2. 获取填充层的蒙版通道
  const maskChannel = doc.channels.find(ch => ch.name === `${fillLayer.name} Mask`);

  // 3. 将maskData写入蒙版通道
  await require('photoshop').imaging.putPixels({
    target: maskChannel,
    data: maskData,
    width: width,
    height: height,
    colorSpace: "Grayscale",
    components: 1,
    bytesPerComponent: 1
  });
}

// 调用示例同首选方案

关键错误修正(针对你之前的失败尝试)

你之前用色彩范围失败的核心原因:Lab色彩空间的L分量范围是0-100,而非0-255,你尝试选择L=255的像素属于无效范围,导致Photoshop选中全部像素。若要使用色彩范围方案,需将蒙版数据转为Lab格式时把L值映射到0-100区间(如maskData[i]/255*100),再用色彩范围选择L接近100的像素,但此方法精度不如通道方案。

内容的提问来源于stack exchange,提问作者Shankar Ramamoorthy

火山引擎 最新活动