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

使用Robot.js截取的截图颜色错乱,如何解决?

问题解决:Robot.js截图转PNG颜色错乱修复

核心原因

Robot.js的captureScreen()返回的原始像素缓冲区是BGRA(蓝、绿、红、透明度)格式,而你指定的PNG颜色类型6要求的是RGBA(红、绿、蓝、透明度)格式,通道顺序不匹配直接导致了颜色错乱。

修复后的完整代码

修改像素数据处理逻辑,交换每个像素的红、蓝通道,同时保留PNG要求的行过滤符(每行开头的0):

const fs = require('fs');
const zlib = require('zlib');
const robot = require("@jitsi/robotjs");

const { width, height } = robot.getScreenSize();
const bitDepth = 8;
const colorType = 6;
const bytesPerPixel = 4;
const rawPixelData = robot.captureScreen().image;

// 修复:将BGRA转RGBA,同时添加PNG行过滤符
const filteredData = Buffer.alloc((width * bytesPerPixel + 1) * height);
for (let i = 0; i < height; i++) {
  // 写入行过滤符(固定为0)
  filteredData[i * (width * bytesPerPixel + 1)] = 0;
  
  const rowStart = i * width * bytesPerPixel;
  const filteredRowStart = i * (width * bytesPerPixel + 1) + 1;
  
  // 遍历当前行的每个像素,交换B和R通道
  for (let j = 0; j < width; j++) {
    const pixelIndex = rowStart + j * bytesPerPixel;
    const filteredIndex = filteredRowStart + j * bytesPerPixel;
    
    // BGRA -> RGBA:交换蓝色和红色通道位置
    filteredData[filteredIndex] = rawPixelData[pixelIndex + 2];     // 红色通道
    filteredData[filteredIndex + 1] = rawPixelData[pixelIndex + 1]; // 绿色通道(不变)
    filteredData[filteredIndex + 2] = rawPixelData[pixelIndex];     // 蓝色通道
    filteredData[filteredIndex + 3] = rawPixelData[pixelIndex + 3]; // 透明度通道(不变)
  }
};
const compressedData = zlib.deflateSync(filteredData);

function crc32(buf) {
  let crc = 0xffffffff;
  for (let i = 0; i < buf.length; i++) {
    crc ^= buf[i];
    for (let j = 0; j < 8; j++) {
      if (crc & 1) {
        crc = (crc >>> 1) ^ 0xedb88320;
      } else {
        crc >>>= 1;
      }
    }
  }
  return Buffer.from([(crc ^ 0xffffffff) >>> 24, (crc ^ 0xffffffff) >>> 16, (crc ^ 0xffffffff) >>> 8, (crc ^ 0xffffffff) & 0xff]);
}

function createChunk(type, data) {
  const length = Buffer.alloc(4);
  length.writeUInt32BE(data.length, 0);

  const typeBuffer = Buffer.from(type, "ascii");
  const crc = crc32(Buffer.concat([typeBuffer, data]));

  return Buffer.concat([length, typeBuffer, data, crc]);
}

const pngSignature = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);

const ihdrData = Buffer.alloc(13);
ihdrData.writeUInt32BE(width, 0);
ihdrData.writeUInt32BE(height, 4);
ihdrData.writeUInt8(bitDepth, 8);
ihdrData.writeUInt8(colorType, 9);
ihdrData.writeUInt8(0, 10);
ihdrData.writeUInt8(0, 11);
ihdrData.writeUInt8(0, 12);

const ihdrChunk = createChunk("IHDR", ihdrData);
const idatChunk = createChunk("IDAT", compressedData);
const iendChunk = createChunk("IEND", Buffer.alloc(0));

const pngData = Buffer.concat([pngSignature, ihdrChunk, idatChunk, iendChunk]);

fs.writeFileSync("./output.png", pngData);
console.log("PNG file written: output.png");

关键说明

  • 仅修改了像素通道转换部分,其余PNG块生成、CRC校验等逻辑保持不变,完全基于你原有的代码框架。
  • 无需引入任何额外依赖,仅使用Node.js内置模块和已安装的Robot.js,符合你不安装大体积包的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 13:40:09