# Sketch SVG 导出：Bitmap 图层内嵌 base64 而非矢量路径

**问题标签**: `sketch`, `svg`, `bitmap`, `SvgPicture`, `Image.asset`, `图标导出`
**问题类型**: `资源处理错误`
**严重程度**: 中
**节省时间**: 多次排查 → 1 次识别

---

## 问题描述

从 Sketch 导出 SVG 图标后，在 Flutter 中用 `SvgPicture.asset` 显示，但图标看起来模糊、不清晰，放大后出现像素化，或者根本无法正确着色。

## 问题根因

Sketch 在导出 Bitmap（位图/Image）类型图层时，即使选择 SVG 格式，**实际写入的是 base64 编码的 PNG 数据**，并非矢量路径：

```xml
<!-- 表面是 .svg 文件，实际内容完全不是矢量 -->
<svg viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA..." width="12" height="12"/>
</svg>
```

用 `SvgPicture.asset` 渲染这种文件时：
- 实际显示的是 base64 内嵌的栅格图像，存在分辨率上限
- `colorFilter` 无法对内嵌图像染色（只对矢量 path 有效）
- 在高 DPI 屏幕上仍然模糊

## 如何识别 Bitmap 图层

```javascript
// Sketch 脚本：检测图层类型
const sketch = require('sketch');
const layer = sketch.getSelectedDocument().selectedLayers.layers[0];

console.log(`图层类型: ${layer.type}`);
// Shape / Group / Text / SymbolInstance → 矢量，可导出 SVG
// Image                                 → 位图，应导出 PNG
```

也可以在 Sketch UI 中：点击图层 → 右侧 Inspector → 图层类型标识为 "Image" 则为 Bitmap。

## 正确方案

### 步骤一：导出 PNG 而非 SVG

```javascript
const sketch = require('sketch');
const layer = sketch.find('[name="ic_rate_chart"]', sketch.getSelectedDocument().selectedPage)[0];

if (layer) {
  // 位图图层导出 PNG，@3x 保证高清
  sketch.export(layer, {
    formats: 'png',
    scales: '3',
    output: '/path/to/project/assets/icons/',
  });
  console.log('导出完成: ic_rate_chart@3x.png');
}
```

### 步骤二：Flutter 使用 Image.asset

```dart
// ✅ 正确 - 位图图标用 Image.asset
Image.asset(
  'assets/icons/ic_rate_chart.png',
  width: 12,
  height: 12,
  color: AppColors.textDarkSecondary,  // 单色染色
  colorBlendMode: BlendMode.srcIn,
)

// ✅ 不需要染色时
Image.asset(
  'assets/icons/ic_rate_chart.png',
  width: 12,
  height: 12,
)

// ❌ 错误 - 对 Bitmap SVG 用 SvgPicture，实际是渲染嵌套 PNG
SvgPicture.asset(
  'assets/icons/ic_rate_chart.svg',
  colorFilter: ColorFilter.mode(color, BlendMode.srcIn), // 不生效
)
```

### 步骤三：注册资源

在 `pubspec.yaml` 中确保声明：

```yaml
flutter:
  assets:
    - assets/icons/ic_rate_chart.png
```

## 矢量图标 vs 位图图标的选择

| 图标来源 | 图层类型 | 导出格式 | Flutter 使用方式 |
|--------|--------|--------|----------------|
| Sketch Shape/Group 绘制 | Shape/Group | SVG | `SvgPicture.asset` |
| 粘贴进来的 PNG/JPG | Image | PNG (`scales: '3'`) | `Image.asset` |
| 外部导入的位图 | Image | PNG (`scales: '3'`) | `Image.asset` |
| 含 mask 的复合图标 | Group | SVG（先确认路径正确） | `SvgPicture.asset` |

## 关键原则

1. **导出前先检查图层类型**：`layer.type === 'Image'` 则为 Bitmap，必须用 PNG
2. **不要对内嵌 base64 SVG 使用 colorFilter**：颜色叠加对栅格图像无效
3. **PNG 导出用 `scales: '3'`**：保证 @3x 分辨率，避免在高 DPI 设备上模糊
