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

如何在Office Script中将RGB像素二维数组转换为可插入图片?

在Office Script中将RGB像素数组转换为可插入的图片

由于Office Script不支持Canvas或外部图像处理库,我们可以通过手动构造BMP格式的二进制数据来实现转换,再将其转为Base64后使用addImage插入。以下是具体实现方案:

核心思路

BMP(位图)是一种无压缩的图像格式,结构清晰,可通过拼接二进制数据手动生成。我们需要构建BMP的文件头、信息头,再将像素数据按BMP的要求(倒序行、补位对齐)整理后拼接,最终转成Base64编码。

完整实现代码

async function main(workbook: ExcelScript.Workbook) {
  // 示例RGB像素数组(2行2列)
  const pixelArray: number[][][] = [
    [[255,255,255],[0,0,0]],
    [[255,255,255],[0,0,0]]
  ];

  // 将像素数组转换为BMP的ArrayBuffer
  const bmpBuffer = convertPixelsToBmp(pixelArray);
  // 转换为Base64编码
  const base64Image = convertToBase64(bmpBuffer);
  // 插入到工作表
  workbook.getWorksheet("ExampleSheet").addImage(base64Image);
}

/**
 * 将RGB像素数组转换为BMP格式的ArrayBuffer
 * @param pixels 二维RGB像素数组,格式为[[[R,G,B], [R,G,B]], ...]
 */
function convertPixelsToBmp(pixels: number[][][]): ArrayBuffer {
  const width = pixels[0].length;
  const height = pixels.length;
  // 每个像素3字节(RGB),每行需要补位到4字节的倍数
  const bytesPerPixel = 3;
  const rowSize = Math.ceil((width * bytesPerPixel) / 4) * 4;
  const pixelDataSize = rowSize * height;
  const fileSize = 54 + pixelDataSize; // BMP文件头(14) + 信息头(40) + 像素数据

  // 创建ArrayBuffer并写入数据
  const buffer = new ArrayBuffer(fileSize);
  const view = new DataView(buffer);

  // 写入BMP文件头(14字节)
  view.setUint8(0, 0x42); // 'B'
  view.setUint8(1, 0x4D); // 'M'
  view.setUint32(2, fileSize, true); // 文件大小(小端序)
  view.setUint32(6, 0, true); // 保留字段
  view.setUint32(10, 54, true); // 像素数据起始位置

  // 写入BMP信息头(40字节)
  view.setUint32(14, 40, true); // 信息头大小
  view.setUint32(18, width, true); // 图像宽度
  view.setUint32(22, height, true); // 图像高度
  view.setUint16(26, 1, true); // 平面数
  view.setUint16(28, 24, true); // 位深度(24位RGB)
  view.setUint32(30, 0, true); // 压缩方式(无压缩)
  view.setUint32(34, pixelDataSize, true); // 像素数据大小
  view.setUint32(38, 2835, true); // 水平分辨率(像素/米,默认值)
  view.setUint32(42, 2835, true); // 垂直分辨率
  view.setUint32(46, 0, true); // 调色板颜色数
  view.setUint32(50, 0, true); // 重要颜色数

  // 写入像素数据(BMP要求行倒序,且每行补位)
  let offset = 54;
  for (let y = height - 1; y >= 0; y--) { // 从最后一行开始写
    const row = pixels[y];
    for (let x = 0; x < width; x++) {
      const [r, g, b] = row[x];
      view.setUint8(offset++, b); // BMP是BGR顺序
      view.setUint8(offset++, g);
      view.setUint8(offset++, r);
    }
    // 补位到4字节倍数
    const padding = rowSize - width * bytesPerPixel;
    for (let i = 0; i < padding; i++) {
      view.setUint8(offset++, 0);
    }
  }

  return buffer;
}

/**
 * 将ArrayBuffer转换为Base64编码
 * @param buffer 待转换的ArrayBuffer
 */
function convertToBase64(buffer: ArrayBuffer): string {
  const bytes = new Uint8Array(buffer);
  let binary = '';
  for (let i = 0; i < bytes.length; i++) {
    binary += String.fromCharCode(bytes[i]);
  }
  return `data:image/bmp;base64,${btoa(binary)}`;
}

代码说明

  • convertPixelsToBmp函数:
    • 先计算BMP文件的各项参数(宽度、高度、行大小、文件总大小)
    • 依次写入BMP的文件头和信息头,严格遵循BMP格式规范
    • 按BMP要求的BGR顺序、倒序行、行补位规则写入像素数据
  • convertToBase64函数:将ArrayBuffer转为二进制字符串,再用btoa编码为Base64,同时加上BMP的MIME前缀
  • 主函数:使用示例像素数组完成转换并插入到指定工作表

注意事项

  • 该实现仅支持24位RGB像素(无Alpha通道),如果需要透明通道可调整为32位BMP格式
  • 像素数组需保证每行长度一致(即图片宽度固定)
  • 大尺寸图片可能会因Office Script的内存限制影响性能,建议用于小图标或简单图形

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 01:38:40