npm package: @kyohxt/clipboard
Description: 跨平台剪贴板操作的 Node.js addon 模块
Author: kyohxt
Latest version: 1.3.0

# 跨平台剪贴板操作 Node.js Addon

一个高性能的跨平台 Node.js 原生扩展模块，用于操作系统剪贴板中的图片数据。支持 macOS、Windows 和 Linux 系统。

## 功能特性

- ✅ **跨平台支持**: 兼容 macOS、Windows 和 Linux
- ✅ **图片格式支持**: PNG、JPEG、BMP 等常见格式
- ✅ **高性能**: 使用原生 C++ 实现，性能优异
- ✅ **简单易用**: 提供友好的 JavaScript API
- ✅ **内存安全**: 自动管理内存，避免内存泄漏
- ✅ **异步支持**: 支持 Promise 和回调函数
- ✅ **支持本地文件路径**: 可直接通过文件路径将图片复制到剪贴板

## 系统要求

- **Node.js**: >= 18.16.0
- **操作系统**: 
  - macOS 10.9+
  - Windows 7+
  - Linux (需要 X11 支持)

### 系统依赖

#### macOS
```bash
# 需要 Xcode Command Line Tools
xcode-select --install
```

#### Windows
```bash
# 需要 Visual Studio Build Tools 或 Visual Studio
# 可以通过以下命令安装：
npm install --global windows-build-tools
```

#### Linux
```bash
# Ubuntu/Debian
sudo apt-get install build-essential libx11-dev

# CentOS/RHEL/Fedora
sudo yum install gcc-c++ libX11-devel
# 或者 (较新版本)
sudo dnf install gcc-c++ libX11-devel
```

## 安装

### 从源码安装

```bash
# 克隆或下载项目
cd clipboard-addon

# 安装依赖
npm install

# 编译原生模块
npm run build
```

### 编译命令

```bash
# 清理构建文件
npm run clean

# 重新构建
npm run build

# 或者使用 node-gyp 直接操作
npx node-gyp clean
npx node-gyp configure
npx node-gyp build
```

## 使用方法

### 基本用法

```javascript
const clipboard = require('./index');

// 检查剪贴板是否包含图片
if (clipboard.hasImageData()) {
    console.log('剪贴板包含图片数据');
}

// 从剪贴板获取图片数据
const imageData = clipboard.getImageData();
if (imageData) {
    console.log(`格式: ${imageData.format}`);
    console.log(`大小: ${imageData.data.length} 字节`);
}

// 清空剪贴板
clipboard.clear();
```

### 从远程 URL 下载图片到剪贴板

```javascript
const clipboard = require('./index');
const https = require('https');

function downloadImageToClipboard(url) {
    return new Promise((resolve, reject) => {
        https.get(url, (response) => {
            if (response.statusCode !== 200) {
                reject(new Error(`HTTP ${response.statusCode}`));
                return;
            }
            
            const chunks = [];
            response.on('data', chunk => chunks.push(chunk));
            response.on('end', () => {
                const imageBuffer = Buffer.concat(chunks);
                
                // 根据 Content-Type 确定格式
                let format = 'png';
                const contentType = response.headers['content-type'];
                if (contentType && contentType.includes('jpeg')) {
                    format = 'jpg';
                }
                
                // 设置到剪贴板
                const success = clipboard.setImageData(imageBuffer, format);
                if (success) {
                    resolve({ size: imageBuffer.length, format });
                } else {
                    reject(new Error('设置剪贴板失败'));
                }
            });
        }).on('error', reject);
    });
}

// 使用示例
downloadImageToClipboard('https://example.com/image.png')
    .then(result => {
        console.log(`图片已复制到剪贴板: ${result.size} 字节, ${result.format} 格式`);
    })
    .catch(console.error);
```

### 直接从本地文件路径复制图片到剪贴板

```javascript
const clipboard = require('./index');

// 直接通过文件路径将图片复制到剪贴板
const success = clipboard.setImageFile('./path/to/image.png');
if (success) {
    console.log('图片已成功复制到剪贴板！');
} else {
    console.log('复制失败');
}
```

### 保存剪贴板图片到文件

```javascript
const clipboard = require('./index');
const fs = require('fs');

function saveClipboardImage(outputPath) {
    if (!clipboard.hasImageData()) {
        console.log('剪贴板中没有图片数据');
        return false;
    }
    
    const imageData = clipboard.getImageData();
    if (!imageData) {
        console.log('无法读取剪贴板数据');
        return false;
    }
    
    // 添加文件扩展名
    if (!outputPath.includes('.')) {
        outputPath += `.${imageData.format}`;
    }
    
    fs.writeFileSync(outputPath, imageData.data);
    console.log(`图片已保存到: ${outputPath}`);
    return true;
}

// 使用示例
saveClipboardImage('./clipboard_image');
```

## API 参考

### `setImageData(imageBuffer, format)`

将图片数据设置到剪贴板。

**参数:**
- `imageBuffer` (Buffer): 图片的二进制数据
- `format` (string, 可选): 图片格式，默认为 'png'。支持: 'png', 'jpg', 'jpeg', 'bmp'

**返回值:**
- `boolean`: 成功返回 `true`，失败返回 `false`

### `setImageFile(imagePath)`

通过文件路径将图片设置到剪贴板。

**参数:**
- `imagePath` (string): 图片文件的路径

**返回值:**
- `boolean`: 成功返回 `true`，失败返回 `false`

### `getImageData()`

从剪贴板获取图片数据。

**返回值:**
- `Object|null`: 成功返回包含图片数据的对象，失败返回 `null`
  - `data` (Buffer): 图片的二进制数据
  - `format` (string): 图片格式

### `hasImageData()`

检查剪贴板是否包含图片数据。

**返回值:**
- `boolean`: 包含图片返回 `true`，否则返回 `false`

### `clear()`

清空剪贴板。

**返回值:**
- `boolean`: 成功返回 `true`，失败返回 `false`

## 运行示例

项目包含了完整的使用示例：

```bash
# 运行基本测试
node test.js

# 运行使用示例（包含新的 setImageFile 功能）
node example.js

# 运行专门测试 setImageFile 功能的测试
node test_image_file.js
```

## 项目结构

```
clipboard-addon/
├── src/                    # C++ 源代码
│   ├── clipboard.h         # 头文件
│   ├── clipboard.cpp       # 主实现文件
│   ├── clipboard_mac.mm    # macOS 实现
│   ├── clipboard_win.cpp   # Windows 实现
│   └── clipboard_linux.cpp # Linux 实现
├── binding.gyp             # 构建配置
├── package.json            # 项目配置
├── index.js                # JavaScript 接口
├── test.js                 # 测试文件
├── example.js              # 使用示例
├── test_image_file.js      # setImageFile 功能测试
└── README.md               # 说明文档
```

## 平台特定说明

### macOS
- 使用 Cocoa/AppKit 框架
- 支持 PNG、TIFF 等格式
- 自动处理格式转换

### Windows
- 使用 Win32 API
- 支持多种剪贴板格式
- 自动注册自定义格式

### Linux
- 使用 X11 API
- 需要运行 X Window System
- 支持 CLIPBOARD 选择

## 故障排除

### 编译错误

1. **缺少构建工具**
   ```bash
   # macOS
   xcode-select --install
   
   # Windows
   npm install --global windows-build-tools
   
   # Linux
   sudo apt-get install build-essential
   ```

2. **Node.js 版本不兼容**
   ```bash
   # 检查版本
   node --version
   
   # 升级到 18.16.0+
   nvm install 18.16.0
   nvm use 18.16.0
   ```

3. **权限问题**
   ```bash
   # 清理并重新构建
   npm run clean
   npm run build
   ```

### 运行时错误

1. **Linux 上的 X11 错误**
   ```bash
   # 确保安装了 X11 开发库
   sudo apt-get install libx11-dev
   
   # 检查 DISPLAY 环境变量
   echo $DISPLAY
   ```

2. **剪贴板访问权限**
   - macOS: 可能需要在系统偏好设置中授予应用权限
   - Windows: 确保没有其他应用独占剪贴板
   - Linux: 确保在 X11 环境中运行

## 性能优化

- 使用 Buffer 而不是字符串处理二进制数据
- 避免频繁的剪贴板操作
- 大图片数据建议进行压缩
- 及时释放不需要的图片数据

## 许可证

MIT License

## 贡献

欢迎提交 Issue 和 Pull Request！

## 更新日志

### v1.1.0
- 新增 setImageFile 功能，支持直接通过文件路径将图片复制到剪贴板

### v1.0.0
- 初始版本
- 支持 macOS、Windows、Linux
- 基本的图片剪贴板操作功能