npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

librawspeed

v1.0.129

Published

Node.js Native Addon for LibRaw - Process RAW image files with JavaScript

Readme

LibRaw Node.js

一个使用 LibRaw 库处理 RAW 图像文件的高性能 Node.js 原生插件。

npm version Node.js Version License: MIT Build Status NPM Downloads

功能特性

  • 100+ RAW 格式 - Canon、Nikon、Sony、Adobe DNG 等
  • 全面的元数据 - EXIF 数据、相机设置、尺寸、镜头信息
  • 高级色彩信息 - 色彩矩阵、白平衡、校准数据
  • 图像处理管道 - 完整的 dcraw 兼容处理链
  • 缩略图提取 - 高质量嵌入式缩略图提取
  • RAW 转 JPEG 转换 - 🆕 高性能 JPEG 导出与优化
  • 批量处理 - 🆕 使用智能设置处理数百个文件
  • AI 驱动设置 - 🆕 基于图像分析的自动质量优化
  • 内存操作 - 完全在内存中处理图像
  • 多种输出格式 - PPM、TIFF、JPEG 与高级压缩选项
  • 缓冲区创建 API - 🆕 直接在内存中创建图像缓冲区(JPEG、PNG、WebP、AVIF、TIFF、PPM、缩略图)
  • 基于流的处理 - 🆕 返回数据流而不是写入文件
  • 缓冲区支持 - 从内存缓冲区加载 RAW 数据
  • 配置控制 - 伽马、亮度、色彩空间设置
  • 高性能 - 原生 C++ 处理与 JavaScript 便利性
  • 内存高效 - 适当的资源管理和清理
  • 基于 Promise 的 API - 现代 async/await 支持
  • 跨平台 - Windows、macOS、Linux 支持(已测试 Windows)
  • 1000+ 相机支持 - LibRaw 的广泛相机数据库
  • 全面测试 - 使用真实 RAW 文件 100% 测试覆盖
  • 生产就绪 - 经过多种相机格式实战测试

支持的格式

LibRaw 支持 100+ RAW 格式,包括:

| 制造商 | 格式 | | -------------------- | ---------------------- | | 佳能 | .CR2, .CR3, .CRW | | 尼康 | .NEF, .NRW | | 索尼 | .ARW, .SRF, .SR2 | | Adobe | .DNG | | 富士 | .RAF | | 奥林巴斯 | .ORF | | 松下 | .RW2 | | 宾得 | .PEF | | 徕卡 | .DNG, .RWL | | 还有更多... | 总共 100+ 格式 |

安装

📦 从 NPM 注册表

npm install librawspeed

版本 1.0.18 现已在 npmjs.com 上可用!🎉

🛠️ 构建要求

  • Node.js 14.0.0 或更高版本
  • Python 2.7 或 3.x(用于 node-gyp)
  • C++ 编译器
    • Windows: Visual Studio Build Tools 或 Visual Studio Community
    • macOS: Xcode Command Line Tools 或 Xcode
    • Linux: build-essential 包

💡 提示:node-gyp 会自动处理构建工具,无需手动安装 make 等工具

🔧 环境检查

安装前可以检查环境是否满足要求:

npm run check:env

⚠️ 故障排除

如果安装失败,请尝试:

# 清理并重新安装
npm run clean
npm run rebuild

# 或强制重新构建
npm install --force

常见问题:

  1. Python 未找到

    npm config set python python3
  2. 编译器未找到

    # Windows
    npm install --global windows-build-tools
       
    # macOS
    xcode-select --install
       
    # Linux
    sudo apt-get install build-essential

🚀 快速验证

安装后,验证包是否正常工作:

node -e "const LibRaw = require('librawspeed'); console.log('LibRaw version:', LibRaw.getVersion());"

预期输出:LibRaw version: 0.21.4-Release

先决条件(从源码构建)

  • Node.js 14.0.0 或更高版本
  • Python 3.x(用于 node-gyp)
  • Visual Studio Build Tools(Windows)
  • Xcode Command Line Tools(macOS)
  • build-essential(Linux)

🛠️ 交叉编译支持

此项目支持多平台交叉编译。有关详细工具链要求和设置说明,请参阅交叉编译指南

支持的平台:

  • ✅ Windows x64
  • ✅ macOS x64(Intel)
  • ✅ macOS ARM64(Apple Silicon)
  • ✅ Linux x64
  • ✅ Linux ARM64

快速设置:

# 安装所有交叉编译工具链
brew install mingw-w64 aarch64-apple-darwin24-gcc-15 musl-cross

# 构建所有平台
npm run cross-compile:all

快速开始

const LibRaw = require("librawspeed");

async function processRAW() {
  // 🆕 检查文件是否为 LibRaw 支持的 RAW 格式
  const checkResult = LibRaw.isRawFile('photo.cr2');
  if (!checkResult.isRawFile) {
    console.log('不是支持的 RAW 文件:', checkResult.message);
    return;
  }
  
  const processor = new LibRaw();

  try {
    // 加载 RAW 文件
    await processor.loadFile("photo.cr2");

    // 🆕 新功能:缓冲区创建 API - 直接在内存中创建图像
    // 首先处理 RAW 数据
    await processor.processImage();

    // 创建 JPEG 缓冲区而不写入文件
    const jpegBuffer = await processor.createJPEGBuffer({
      quality: 85,
      width: 1920,
      progressive: true,
    });

    console.log(`JPEG 缓冲区已创建:${jpegBuffer.buffer.length} 字节`);

    // 并行创建多种格式
    const [pngResult, webpResult, thumbResult] = await Promise.all([
      processor.createPNGBuffer({ width: 1200, compressionLevel: 6 }),
      processor.createWebPBuffer({ quality: 80, width: 1200 }),
      processor.createThumbnailJPEGBuffer({ maxSize: 300 }),
    ]);

    // 直接使用缓冲区(例如,通过 HTTP 发送、存储到数据库等)
    // 无需临时文件!

    console.log(`PNG:${pngResult.buffer.length} 字节`);
    console.log(`WebP:${webpResult.buffer.length} 字节`);
    console.log(`缩略图:${thumbResult.buffer.length} 字节`);

    // 🆕 新功能:高性能 JPEG 转换(传统方法仍然可用)
    // 使用高级选项将 RAW 转换为 JPEG
    const jpegResult = await processor.convertToJPEG("output.jpg", {
      quality: 85, // JPEG 质量(1-100)
      width: 1920, // 调整到 1920px 宽度
      progressive: true, // 用于网络的渐进式 JPEG
      mozjpeg: true, // 使用 MozJPEG 获得更好的压缩
      chromaSubsampling: "4:2:0", // 优化文件大小
    });

    console.log(
      `JPEG 已保存:${jpegResult.metadata.fileSize.compressed / 1024}KB`
    );
    console.log(
      `压缩率:${jpegResult.metadata.fileSize.compressionRatio}x`
    );
    console.log(`处理时间:${jpegResult.metadata.processing.timeMs}ms`);

    // 🆕 AI 驱动的优化设置
    const analysis = await processor.getOptimalJPEGSettings({ usage: "web" });
    console.log(`推荐质量:${analysis.recommended.quality}`);
    console.log(`图像类别:${analysis.imageAnalysis.category}`);

    // 应用优化设置
    await processor.convertToJPEG("optimized.jpg", analysis.recommended);

    // 提取全面的元数据
    const [metadata, advanced, lens, color] = await Promise.all([
      processor.getMetadata(),
      processor.getAdvancedMetadata(),
      processor.getLensInfo(),
      processor.getColorInfo(),
    ]);

    console.log("相机:", metadata.make, metadata.model);
    console.log("镜头:", lens.lensName || "未知");
    console.log(
      "设置:",
      `ISO ${metadata.iso}, f/${metadata.aperture}, ${metadata.focalLength}mm`
    );
    console.log(
      "色彩:",
      `${color.colors} 通道,黑电平 ${color.blackLevel}`
    );

    // 传统处理管道(仍然可用)
    await processor.setOutputParams({
      bright: 1.1, // 亮度调整
      gamma: [2.2, 4.5], // 伽马曲线
      output_bps: 16, // 16 位输出
      no_auto_bright: false, // 启用自动亮度
    });

    // 处理图像
    await processor.raw2Image();
    await processor.processImage();

    // 在内存中创建处理后的图像
    const imageData = await processor.createMemoryImage();
    console.log(
      `已处理:${imageData.width}x${imageData.height},${imageData.dataSize} 字节`
    );

    // 导出到文件
    await processor.writeTIFF("output.tiff");
    await processor.writeThumbnail("thumbnail.jpg");

    // 提取高质量缩略图
    const thumbnailData = await processor.createMemoryThumbnail();
    console.log(`缩略图:${thumbnailData.width}x${thumbnailData.height}`);

    // 始终清理资源
    await processor.close();
  } catch (error) {
    console.error("错误:", error.message);
  }
}

processRAW();

完整的 API 覆盖

此包装器提供全面的 LibRaw 功能,包含 50+ 方法,分为 8 个类别:

🔧 核心操作(10 个方法)

  • 文件加载(loadFileloadBuffer
  • 处理管道(raw2ImageprocessImagesubtractBlack
  • 资源管理(closefreeImage

📊 元数据和信息(12 个方法)

  • 基本元数据(getMetadatagetImageSizegetFileInfo
  • 高级元数据(getAdvancedMetadatagetLensInfogetColorInfo
  • 相机矩阵(getCameraColorMatrixgetRGBCameraMatrix

🖼️ 图像处理(8 个方法)

  • 内存操作(createMemoryImagecreateMemoryThumbnail
  • 格式转换(getMemImageFormatcopyMemImage
  • 处理控制(adjustMaximumadjustSizesInfoOnly

📄 文件写入器(6 个方法)

  • 输出格式(writePPMwriteTIFFwriteThumbnail
  • 格式验证和质量控制

⚙️ 配置(4 个方法)

  • 参数控制(setOutputParamsgetOutputParams
  • 处理设置和色彩空间管理

🔍 扩展实用工具(8 个方法)

  • 格式检测(isFloatingPointisFujiRotatedisSRAW
  • 相机特定功能(isNikonSRAWisCoolscanNEF

🎨 色彩操作(3 个方法)

  • 色彩分析(getColorAtconvertFloatToInt
  • 白平衡和色彩矩阵操作

📈 静态方法(4 个方法)

  • 库信息(getVersiongetCapabilities
  • 相机数据库(getCameraListgetCameraCount

所有方法都经过全面测试,可用于生产环境!

🆕 缓冲区创建 API(新功能)

直接内存缓冲区创建

直接在内存中创建图像缓冲区,无需写入文件。非常适合 Web 应用程序、API 和流式工作流程。

可用的缓冲区方法

const processor = new LibRaw();
await processor.loadFile("photo.cr2");
await processor.processImage();

// 创建不同格式的缓冲区
const jpegBuffer = await processor.createJPEGBuffer(options);
const pngBuffer = await processor.createPNGBuffer(options);
const webpBuffer = await processor.createWebPBuffer(options);
const avifBuffer = await processor.createAVIFBuffer(options);
const tiffBuffer = await processor.createTIFFBuffer(options);
const ppmBuffer = await processor.createPPMBuffer();

// 无需完整处理即可提取缩略图缓冲区
const processor2 = new LibRaw();
await processor2.loadFile("photo.cr2");
const thumbBuffer = await processor2.createThumbnailJPEGBuffer(options);

缓冲区创建选项

JPEG 缓冲区选项
{
  quality: 85,          // 1-100(默认:85)
  width: 1200,         // 目标宽度
  height: 800,         // 目标高度
  progressive: true,   // 渐进式 JPEG
  fastMode: false,     // 速度与质量权衡
  effort: 4           // 编码努力程度 1-8
}
PNG 缓冲区选项
{
  width: 1200,           // 目标宽度
  height: 800,          // 目标高度
  compressionLevel: 6,  // 0-9(默认:6)
  fastMode: false       // 速度与大小权衡
}
WebP 缓冲区选项
{
  quality: 80,         // 1-100(默认:80)
  width: 1200,        // 目标宽度
  height: 800,        // 目标高度
  lossless: false,    // 无损模式
  effort: 4,          // 编码努力程度 0-6
  fastMode: false     // 速度优化
}
AVIF 缓冲区选项
{
  quality: 50,         // 1-100(默认:50)
  width: 1200,        // 目标宽度
  height: 800,        // 目标高度
  lossless: false,    // 无损模式
  effort: 4           // 编码努力程度 0-9
}
TIFF 缓冲区选项
{
  width: 1200,              // 目标宽度
  height: 800,             // 目标高度
  compression: 'lzw',      // 'none', 'lzw', 'zip'
  predictor: 'horizontal'  // 压缩预测器
}
缩略图缓冲区选项
{
  maxSize: 300,       // 最大尺寸
  quality: 85,        // JPEG 质量 1-100
  fastMode: false     // 速度优化
}

使用示例

Web API 响应
app.get("/api/photo/:id/thumbnail", async (req, res) => {
  const processor = new LibRaw();
  try {
    await processor.loadFile(`photos/${req.params.id}.cr2`);

    const result = await processor.createThumbnailJPEGBuffer({
      maxSize: 300,
      quality: 85,
    });

    res.set({
      "Content-Type": "image/jpeg",
      "Content-Length": result.buffer.length,
      "Cache-Control": "public, max-age=86400",
    });

    res.send(result.buffer);
  } finally {
    await processor.close();
  }
});
多格式生成
async function generateFormats(rawFile, outputDir) {
  const processor = new LibRaw();
  await processor.loadFile(rawFile);
  await processor.processImage();

  // 并行生成所有格式
  const [jpeg, png, webp, avif] = await Promise.all([
    processor.createJPEGBuffer({ quality: 85, width: 1920 }),
    processor.createPNGBuffer({ width: 1200, compressionLevel: 6 }),
    processor.createWebPBuffer({ quality: 80, width: 1920 }),
    processor.createAVIFBuffer({ quality: 50, width: 1200 }),
  ]);

  // 根据需要保存或处理缓冲区
  fs.writeFileSync(`${outputDir}/image.jpg`, jpeg.buffer);
  fs.writeFileSync(`${outputDir}/image.png`, png.buffer);
  fs.writeFileSync(`${outputDir}/image.webp`, webp.buffer);
  fs.writeFileSync(`${outputDir}/image.avif`, avif.buffer);

  await processor.close();
}
流式上传
async function uploadToCloud(rawFile) {
  const processor = new LibRaw();
  await processor.loadFile(rawFile);
  await processor.processImage();

  const webpResult = await processor.createWebPBuffer({
    quality: 80,
    width: 1600,
  });

  // 直接将缓冲区上传到云存储
  const uploadResult = await cloudStorage.upload(webpResult.buffer, {
    contentType: "image/webp",
    fileName: "processed-image.webp",
  });

  await processor.close();
  return uploadResult;
}

缓冲区结果结构

所有缓冲区创建方法都返回一致的结果结构:

{
  success: true,
  buffer: Buffer,              // 创建的图像缓冲区
  metadata: {
    format: "JPEG",            // 输出格式
    outputDimensions: {        // 最终图像尺寸
      width: 1920,
      height: 1280
    },
    fileSize: {
      original: 50331648,      // 原始处理图像大小
      compressed: 245760,      // 缓冲区大小
      compressionRatio: "204.8" // 压缩比
    },
    processing: {
      timeMs: "45.23",         // 处理时间
      throughputMBps: "15.4"   // 处理吞吐量
    },
    options: {                 // 应用的选项
      quality: 85,
      width: 1920,
      // ... 其他选项
    }
  }
}

性能特征

| 格式 | 典型大小(1920px) | 创建时间 | 压缩比 | | ---------- | --------------------- | ------------- | ----------------- | | JPEG | 80-400KB | 200-500ms | 50-200x | | PNG | 1-4MB | 400-800ms | 12-50x | | WebP | 50-300KB | 100-300ms | 60-300x | | AVIF | 30-150KB | 300-800ms | 100-500x | | TIFF (LZW) | 2-8MB | 100-200ms | 6-25x | | PPM | 11-45MB | 50-100ms | 1x(未压缩) | | 缩略图 | 5-50KB | 50-150ms | 200-1000x |

🆕 JPEG 转换(增强功能)

高性能 RAW 转 JPEG 转换

将 RAW 文件转换为优化的 JPEG 格式,具有高级压缩选项和智能设置分析。

基本 JPEG 转换

const processor = new LibRaw();
await processor.loadFile("photo.cr2");

// 使用默认设置的基本转换
const result = await processor.convertToJPEG("output.jpg");

// 使用自定义选项的高质量转换
const result = await processor.convertToJPEG("high-quality.jpg", {
  quality: 95, // JPEG 质量(1-100)
  chromaSubsampling: "4:2:2", // 更好的色度用于打印
  trellisQuantisation: true, // 高级压缩
  optimizeCoding: true, // 霍夫曼优化
});

console.log(`文件大小:${result.metadata.fileSize.compressed / 1024}KB`);
console.log(`压缩率:${result.metadata.fileSize.compressionRatio}x`);
console.log(`处理时间:${result.metadata.processing.timeMs}ms`);

网络优化的调整大小转换

// 为网络使用转换和调整大小
const webResult = await processor.convertToJPEG("web-optimized.jpg", {
  quality: 80, // 网络使用的良好质量
  width: 1920, // 调整到 1920px 宽度(保持宽高比)
  progressive: true, // 渐进式加载
  mozjpeg: true, // 卓越的压缩算法
  optimizeScans: true, // 优化以更快加载
});

// 创建缩略图
const thumbResult = await processor.convertToJPEG("thumbnail.jpg", {
  quality: 85,
  width: 400,
  height: 300,
  chromaSubsampling: "4:2:2", // 小图像的更好质量
});

AI 驱动的优化设置

// 分析图像并获取推荐设置
const analysis = await processor.getOptimalJPEGSettings({ usage: "web" });

console.log("推荐设置:", analysis.recommended);
console.log("图像分析:", analysis.imageAnalysis);

// 应用推荐设置
const optimizedResult = await processor.convertToJPEG(
  "optimized.jpg",
  analysis.recommended
);

批量转换

// 使用优化设置转换多个 RAW 文件
const inputFiles = ["photo1.cr2", "photo2.nef", "photo3.arw"];
const outputDir = "./jpeg-output";

const batchResult = await processor.batchConvertToJPEG(inputFiles, outputDir, {
  quality: 80,
  width: 1920,
  progressive: true,
  mozjpeg: true,
});

console.log(
  `已处理:${batchResult.summary.processed}/${batchResult.summary.total}`
);
console.log(
  `成功率:${(
    (batchResult.summary.processed / batchResult.summary.total) *
    100
  ).toFixed(1)}%`
);
console.log(
  `节省空间:${(
    (batchResult.summary.totalOriginalSize -
      batchResult.summary.totalCompressedSize) /
    1024 /
    1024
  ).toFixed(1)}MB`
);

JPEG 转换选项

| 选项 | 类型 | 默认值 | 描述 | | --------------------- | ------- | ------- | ---------------------------------------------------- | | quality | number | 85 | JPEG 质量(1-100,越高质量越好) | | width | number | - | 目标宽度(像素,保持宽高比) | | height | number | - | 目标高度(像素,保持宽高比) | | progressive | boolean | false | 启用渐进式 JPEG 用于网络优化 | | mozjpeg | boolean | true | 使用 MozJPEG 编码器获得卓越压缩 | | chromaSubsampling | string | '4:2:0' | 色度子采样('4:4:4', '4:2:2'*, '4:2:0') | | trellisQuantisation | boolean | false | 高级压缩技术 | | optimizeScans | boolean | false | 优化扫描顺序用于渐进式加载 | | optimizeCoding | boolean | true | 优化霍夫曼编码表 | | colorSpace | string | 'srgb' | 输出色彩空间('srgb', 'rec2020', 'p3', 'cmyk') |

*注意:由于 Sharp 库限制,'4:2:2' 色度子采样自动映射到 '4:4:4'。

性能特征

  • 处理速度:在现代硬件上 70-140 MB/s
  • 压缩比:典型压缩 2-10x(因内容而异)
  • 内存效率:大文件的流式处理
  • 质量保持:Q85+ 设置下视觉无损

使用预设

网络优化

{
  quality: 80,
  width: 1920,
  progressive: true,
  mozjpeg: true,
  chromaSubsampling: '4:2:0',
  optimizeScans: true
}

打印质量

{
  quality: 95,
  chromaSubsampling: '4:2:2',
  trellisQuantisation: true,
  optimizeCoding: true,
  mozjpeg: true
}

归档/最大质量

{
  quality: 98,
  chromaSubsampling: '4:4:4',
  trellisQuantisation: true,
  optimizeCoding: true
}

缩略图生成

{
  quality: 85,
  width: 800,
  chromaSubsampling: '4:2:2',
  mozjpeg: true
}

命令行工具

单个文件转换

node examples/jpeg-conversion-example.js photo.cr2

批量转换

# 网络优化的批量转换
node scripts/batch-jpeg-conversion.js ./raw-photos ./web-gallery 1

# 打印质量转换
node scripts/batch-jpeg-conversion.js ./raw-photos ./print-gallery 2

# 归档质量转换
node scripts/batch-jpeg-conversion.js ./raw-photos ./archive-gallery 3

NPM 脚本

# 运行 JPEG 转换测试
npm run test:jpeg-conversion

# 使用 CLI 界面批量转换
npm run convert:jpeg <input-dir> [output-dir] [preset]

## API 参考

### 文件操作

#### `new LibRaw()`

创建一个新的 LibRaw 处理器实例。

#### `loadFile(filename)`

从文件系统加载 RAW 文件。

- **filename** `{string}` - RAW 文件路径
- **返回** `{Promise<boolean>}` - 成功状态

#### `loadBuffer(buffer)`

从内存缓冲区加载 RAW 数据。

- **buffer** `{Buffer}` - 包含 RAW 数据的缓冲区
- **返回** `{Promise<boolean>}` - 成功状态

#### `close()`

关闭处理器并释放所有资源。

- **返回** `{Promise<boolean>}` - 成功状态

### 元数据和信息

#### `getMetadata()`

从加载的 RAW 文件中提取基本元数据。

- **返回** `{Promise<Object>}` - 包含以下内容的元数据对象:
  ```javascript
  {
    make: 'Canon',           // 相机制造商
    model: 'EOS R5',         // 相机型号
    software: '1.3.1',       // 相机软件版本
    width: 8192,             // 处理后的图像宽度
    height: 5464,            // 处理后的图像高度
    rawWidth: 8280,          // RAW 传感器宽度
    rawHeight: 5520,         // RAW 传感器高度
    colors: 3,               // 颜色通道数
    filters: 0x94949494,     // 颜色滤镜模式
    iso: 800,                // ISO 感光度
    shutterSpeed: 0.004,     // 快门速度(秒)
    aperture: 2.8,           // 光圈 f 值
    focalLength: 85,         // 焦距(毫米)
    timestamp: 1640995200    // 拍摄时间戳(Unix)
  }

getImageSize()

获取详细的图像尺寸和边距信息。

  • 返回 {Promise<Object>} - 尺寸信息:
    {
      width: 8192,      // 处理后的图像宽度
      height: 5464,     // 处理后的图像高度
      rawWidth: 8280,   // RAW 传感器宽度
      rawHeight: 5520,  // RAW 传感器高度
      topMargin: 16,    // 顶部边距(像素)
      leftMargin: 24,   // 左侧边距(像素)
      iWidth: 8192,     // 内部处理宽度
      iHeight: 5464     // 内部处理高度
    }

getAdvancedMetadata()

获取高级元数据,包括色彩矩阵和校准数据。

  • 返回 {Promise<Object>} - 包含色彩矩阵、黑电平等的高级元数据

getLensInfo()

从 RAW 文件中获取镜头信息。

  • 返回 {Promise<Object>} - 包含名称、焦距范围、序列号的镜头信息

getColorInfo()

获取色彩信息,包括白平衡和色彩矩阵。

  • 返回 {Promise<Object>} - 包含 RGB 矩阵和乘数的色彩信息

图像处理

subtractBlack()

从 RAW 数据中减去黑电平。

  • 返回 {Promise<boolean>} - 成功状态

raw2Image()

将 RAW 数据转换为图像格式。

  • 返回 {Promise<boolean>} - 成功状态

adjustMaximum()

调整图像数据中的最大值。

  • 返回 {Promise<boolean>} - 成功状态

processImage()

使用当前设置执行完整的图像处理。

  • 返回 {Promise<boolean>} - 成功状态

unpackThumbnail()

从 RAW 文件中解包缩略图数据。

  • 返回 {Promise<boolean>} - 成功状态

内存操作

createMemoryImage()

在内存中创建处理后的图像。

  • 返回 {Promise<Object>} - 图像数据对象:
    {
      type: 2,              // 图像类型(1=JPEG, 2=TIFF)
      width: 8192,          // 图像宽度
      height: 5464,         // 图像高度
      colors: 3,            // 颜色通道数
      bits: 16,             // 每样本位数
      dataSize: 268435456,  // 数据大小(字节)
      data: Buffer         // 图像数据缓冲区
    }

createMemoryThumbnail()

在内存中创建缩略图图像。

  • 返回 {Promise<Object>} - 与上述结构相同的缩略图数据对象

文件写入器

writePPM(filename)

将处理后的图像写入为 PPM 文件。

  • filename {string} - 输出文件名
  • 返回 {Promise<boolean>} - 成功状态

writeTIFF(filename)

将处理后的图像写入为 TIFF 文件。

  • filename {string} - 输出文件名
  • 返回 {Promise<boolean>} - 成功状态

writeThumbnail(filename)

将缩略图写入文件。

  • filename {string} - 输出文件名
  • 返回 {Promise<boolean>} - 成功状态

配置

setOutputParams(params)

设置图像处理的输出参数。

  • params {Object} - 参数对象:
    {
      gamma: [2.2, 4.5],     // 伽马校正 [功率, 斜率]
      bright: 1.0,           // 亮度调整
      output_color: 1,       // 输出色彩空间 (0=raw, 1=sRGB, 2=Adobe RGB)
      output_bps: 8,         // 输出每样本位数 (8 或 16)
      user_mul: [1,1,1,1],   // 用户白平衡乘数
      no_auto_bright: false, // 禁用自动亮度
      highlight: 0,          // 高光恢复模式 (0-9)
      output_tiff: false     // 输出 TIFF 格式
    }
  • 返回 {Promise<boolean>} - 成功状态

getOutputParams()

获取当前输出参数。

  • 返回 {Promise<Object>} - 当前参数设置

实用工具函数

isFloatingPoint()

检查图像是否使用浮点数据。

  • 返回 {Promise<boolean>} - 浮点状态

isFujiRotated()

检查图像是否为富士旋转(45度传感器旋转)。

  • 返回 {Promise<boolean>} - 富士旋转状态

isSRAW()

检查图像是否为 sRAW 格式。

  • 返回 {Promise<boolean>} - sRAW 格式状态

isJPEGThumb()

检查缩略图是否为 JPEG 格式。

  • 返回 {Promise<boolean>} - JPEG 缩略图状态

errorCount()

获取处理过程中遇到的错误数量。

  • 返回 {Promise<number>} - 错误计数

静态方法

LibRaw.getVersion()

获取 LibRaw 库版本。

  • 返回 {string} - 版本字符串(例如:"0.21.4-Release")

LibRaw.getCapabilities()

获取 LibRaw 库功能作为位掩码。

  • 返回 {number} - 功能标志

LibRaw.getCameraList()

获取所有支持的相机型号列表。

  • 返回 {string[]} - 相机型号名称数组

LibRaw.getCameraCount()

获取支持的相机型号数量。

  • 返回 {number} - 相机数量(通常 1000+)

LibRaw.isRawFile(filePath) 🆕

检查文件是否为 LibRaw 支持的 RAW 格式。

  • filePath {string} - 要检查的文件路径
  • 返回 {Object} - 检查结果对象:
    {
      isRawFile: boolean,    // 是否为 LibRaw 支持的 RAW 文件
      success: boolean,      // 检查是否成功
      message: string,       // 详细信息
      errorCode?: number     // 错误代码(仅失败时)
    }

示例:

// 检查单个文件
const result = LibRaw.isRawFile('photo.cr2');
if (result.isRawFile) {
  console.log('✅ 这是 LibRaw 支持的 RAW 文件');
} else {
  console.log('❌ 不是支持的 RAW 文件:', result.message);
}

// 过滤目录中的 RAW 文件
const files = fs.readdirSync(dir);
const rawFiles = files.filter(file => 
  LibRaw.isRawFile(path.join(dir, file)).isRawFile
);

// 上传前验证
if (!LibRaw.isRawFile(uploadedFile).isRawFile) {
  throw new Error('请上传 LibRaw 支持的 RAW 格式文件');
}

优势:

  • ✅ 智能识别 - 利用 LibRaw 内部机制,支持 100+ 种 RAW 格式
  • ✅ 无需维护 - 不需要手动维护扩展名列表
  • ✅ 轻量级 - 只进行格式识别,不完全加载文件
  • ✅ 准确可靠 - 基于文件内容判断,而非仅靠扩展名

测试

该库包含涵盖所有主要功能的全面测试套件:

快速测试

# 基本功能测试
npm run test:quick

# 全面的 API 覆盖测试
npm run test:comprehensive

# 新的缓冲区创建方法测试
npm run test:buffer-creation

# 单独的测试套件
npm run test:image-processing    # 图像转换和处理
npm run test:format-conversion   # 输出格式和色彩空间
npm run test:thumbnail-extraction # 缩略图操作

高级测试

# 使用示例图像测试(如果可用)
npm run test:samples
npm run test:compare

# 性能基准测试
npm run test:performance

# 测试所有支持的格式
npm run test:formats

# 缓冲区创建测试套件
npm run test:buffer-creation     # 全面的缓冲区方法测试

# 使用您自己的 RAW 文件测试
npm test path/to/your/photo.cr2

测试覆盖

测试套件提供全面的验证:

  • 测试了 21 个 RAW 文件(佳能 CR3、尼康 NEF、索尼 ARW、富士 RAF、松下 RW2、徕卡 DNG)
  • 100% 缩略图提取成功率
  • 100% 缓冲区创建成功率(7 个新的缓冲区方法)
  • 验证了 6 个相机品牌(佳能、尼康、索尼、富士、松下、徕卡)
  • 测试了多种输出格式(PPM、TIFF、JPEG、PNG、WebP、AVIF 缓冲区)
  • 色彩空间转换(sRGB、Adobe RGB、宽色域、ProPhoto、XYZ)
  • 位深度变化(8 位、16 位处理)
  • 内存操作(缓冲区管理、图像复制、直接缓冲区创建)
  • 错误处理(无效文件、损坏数据、参数验证)
  • 性能基准测试(缓冲区创建速度和压缩比)

缩略图提取

从 RAW 文件中提取高质量缩略图:

const LibRaw = require("librawspeed");

async function extractThumbnails() {
  const processor = new LibRaw();

  try {
    await processor.loadFile("photo.cr2");

    // 检查缩略图是否存在
    const hasThumb = await processor.thumbOK();
    if (hasThumb) {
      // 提取缩略图
      await processor.unpackThumbnail();

      // 获取缩略图数据
      const thumbData = await processor.createMemoryThumbnail();
      console.log(
        `缩略图:${thumbData.width}x${thumbData.height},${thumbData.dataSize} 字节`
      );

      // 保存到文件
      await processor.writeThumbnail("thumbnail.jpg");
    }

    await processor.close();
  } catch (error) {
    console.error("错误:", error.message);
  }
}

批量缩略图提取

从所有 RAW 文件中提取缩略图:

# 从 sample-images/ 中的所有 RAW 文件提取缩略图
npm run extract:thumbnails

这将创建:

  • sample-images/thumbnails/ 中的单独 JPEG 缩略图
  • 交互式画廊查看器(index.html
  • 全面的提取报告

示例结果:

  • 21/21 文件成功处理(100% 成功率)
  • 格式: CR3、NEF、ARW、RAF、RW2、DNG
  • 质量: 380KB - 13.4MB 缩略图(保持原始质量)
  • 性能: 平均提取时间约 50ms

示例输出

📁 加载 RAW 文件:DSC_0006.NEF
📊 提取元数据...

📷 相机信息:
   制造商:尼康
   型号:D5600

📐 图像尺寸:
   处理后:6016 x 4016
   RAW:6016 x 4016

🎯 拍摄参数:
   ISO:200
   光圈:f/6.3
   快门速度:1/250s
   焦距:300mm

🎨 色彩信息:
   颜色:3
   滤镜:0xb4b4b4b4

📅 拍摄日期:2025-06-05T09:48:18.000Z

✅ 完成!

项目结构

librawspeed/
├── src/                         # C++ 源文件
│   ├── addon.cpp               # 主要插件入口点
│   ├── libraw_wrapper.cpp      # LibRaw C++ 包装器(50+ 方法)
│   └── libraw_wrapper.h        # 头文件
├── lib/                        # JavaScript 接口
│   └── index.js               # 主要模块导出
├── test/                       # 全面的测试套件
│   ├── image-processing.test.js    # 图像转换测试
│   ├── format-conversion.test.js   # 格式和色彩空间测试
│   ├── thumbnail-extraction.test.js # 缩略图操作测试
│   ├── comprehensive.test.js       # 组合测试运行器
│   ├── performance.test.js         # 性能基准测试
│   └── all-formats.test.js         # 多格式验证
├── scripts/                    # 实用工具脚本
│   └── extract-thumbnails.js  # 批量缩略图提取器
├── examples/                   # 使用示例
│   ├── basic-example.js       # 基本使用演示
│   └── advanced-demo.js       # 高级处理示例
├── sample-images/              # 示例 RAW 文件和结果
│   ├── thumbnails/            # 提取的缩略图画廊
│   │   ├── index.html         # 交互式查看器
│   │   ├── README.md          # 提取文档
│   │   └── *.jpg              # 21 个提取的缩略图
│   └── *.{CR3,NEF,ARW,RAF,RW2,DNG} # 测试 RAW 文件
├── docs/                       # 文档
│   └── TESTING.md             # 全面的测试指南
├── deps/                       # 依赖项
│   └── LibRaw-Source/         # LibRaw 源代码(跨平台)
│       └── LibRaw-0.21.4/
│           └── build/         # 交叉编译的库
│               ├── win32/     # Windows x64
│               ├── darwin-x64/ # macOS Intel
│               ├── darwin-arm64/ # macOS Apple Silicon
│               ├── linux-x64/ # Linux x64
│               └── linux-arm64/ # Linux ARM64
├── binding.gyp                # 构建配置
├── package.json               # 项目配置
└── README.md                  # 此文件

开发

从源码构建

# 清理之前的构建
npm run clean

# 重新构建
npm run build

# 测试构建
npm run test:quick

添加新功能

  1. src/ 中添加 C++ 实现
  2. lib/ 中更新 JavaScript 包装器
  3. test/ 中添加测试
  4. 更新文档

贡献

  1. Fork 仓库
  2. 创建功能分支(git checkout -b feature/amazing-feature
  3. 提交您的更改(git commit -m 'Add amazing feature'
  4. 推送到分支(git push origin feature/amazing-feature
  5. 打开 Pull Request

路线图

版本 1.0(当前 - 生产就绪)

  • ✅ RAW 文件加载和元数据提取
  • ✅ 全面的 EXIF 数据访问
  • ✅ 内存高效处理
  • ✅ 基于 Promise 的 API
  • 缩略图提取(100% 成功率)
  • 图像处理管道
  • 多种输出格式(PPM、TIFF)
  • 实现了 50+ LibRaw 方法
  • 全面的测试覆盖
  • 验证了 6 个相机品牌
  • 生产就绪的稳定性

版本 2.0(计划中)

  • 🔄 高级图像滤镜和调整
  • 🔄 批量处理优化
  • 🔄 额外的输出格式(JPEG、PNG)
  • 🔄 色彩配置文件管理
  • 🔄 实时预览生成

版本 3.0(未来)

  • 📋 批量处理功能
  • 📋 大文件的流式支持
  • 📋 高级色彩管理
  • 📋 自定义处理器的插件系统

性能

LibRaw Node.js 为 RAW 处理提供卓越的性能:

真实世界基准测试(已测试 Windows)

| 操作 | 文件大小 | 处理时间 | 吞吐量 | 成功率 | | ------------------------- | ---------------- | --------------- | ---------- | ------------ | | 文件加载 | 25MB RAW | 15-30ms | 800MB/s+ | 100% | | 元数据提取 | 任何 RAW | 1-5ms | - | 100% | | 缩略图提取 | 160x120 - 4K | 20-50ms | 400KB/s+ | 100% | | 完整图像处理 | 6000x4000 16位 | 1000-2000ms | 70-140MB/s | 95%+ | | 格式写入 (PPM) | 144MB 输出 | 200-500ms | 300MB/s+ | 100% | | 格式写入 (TIFF) | 144MB 输出 | 800-1200ms | 120MB/s+ | 100% |

内存效率

| 操作 | 峰值内存 | 缓冲区大小 | 清理 | | ------------------------ | ----------- | ------------------- | ---------- | | RAW 加载 | ~50MB | 25MB 文件缓冲区 | ✅ 自动 | | 图像处理 | ~200MB | 144MB 图像缓冲区 | ✅ 自动 | | 缩略图提取 | ~5MB | 2-13MB 缩略图缓冲区 | ✅ 自动 | | 批量处理 | 恒定 | 无内存泄漏 | ✅ 完美 |

测试结果摘要

  • ✅ 21/21 RAW 文件已处理 跨越 6 个相机品牌
  • ✅ 100% 缩略图提取成功(总共 2.5GB 缩略图)
  • ✅ 95%+ 图像处理成功(管道工作流程正常)
  • ✅ 0 内存泄漏 在广泛测试中检测到
  • ✅ 亚秒级 所有格式的元数据提取

故障排除

构建问题

错误:找不到模块 'node-addon-api'

npm install node-addon-api

错误:MSBuild.exe 失败,退出代码:1

  • 安装 Visual Studio Build Tools
  • 确保 Python 3.x 可用

错误:找不到 libraw.dll

npm run build  # 重新构建并复制 DLL

运行时问题

错误:无法打开文件

  • 检查文件路径和权限
  • 验证文件是否为有效的 RAW 格式
  • 确保文件未损坏

🚀 NPM 发布状态

✅ 已发布到 NPM 注册表!

  • [email protected]
  • 发布日期:2025年8月30日
  • 总文件数:487 个文件(4.0 MB 包,18.1 MB 解压后)
  • 注册表npmjs.com

安装命令

npm install librawspeed

下载统计

  • 初始发布:生产就绪,具有全面的测试覆盖
  • 平台:Windows(已测试)、macOS、Linux
  • Node.js:14.0.0+ 兼容

许可证

此项目在 MIT 许可证下授权 - 有关详细信息,请参阅 LICENSE 文件。

致谢

  • LibRaw - 强大的 RAW 处理库
  • Node-API - Node.js 原生插件接口
  • node-gyp - Node.js 原生插件构建工具
  • 摄影社区 - 提供多样化的 RAW 文件进行全面测试
  • 相机制造商 - 佳能、尼康、索尼、富士、松下、徕卡提供优秀的 RAW 格式

测试贡献者

特别感谢使用真实世界 RAW 文件进行的全面测试:

  • 21 个 RAW 文件 跨越 6 个主要相机品牌
  • 100% 缩略图提取成功 验证
  • 生产级稳定性 测试和验证

支持


为摄影和 Node.js 社区用心制作 ❤️