# 图片堆栈 把一串连拍合成一张，RAW 也行

二十张变一张，不用传二十次，也不用 RAW 转换器。

> 把一串连拍的照片合成一张：取平均值消噪点，取中位数把人从画面里去掉，取最亮做星轨，或者给微距做景深合成。CR2、NEF、ARW、DNG、RAF 和 CR3 靠读出相机自己的预览图来打开。全部在你的浏览器里跑。

这是一个浏览器交互工具，地址是 https://abox.tools/zh/stack-images/。文件在运行该浏览器的设备上处理。主动分享和可选联网功能都在页面上说明。下文是它的文字说明；使用工具请打开该地址。

## 你的照片**在浏览器里处理**，无须上传处理。

每一帧的打开、解码、对齐、合成和写出，全都由你自己的浏览器在你自己的机器上完成。二十个 60 MB 的 RAW 文件差不多是一个 G 的照片，其中一个字节也没有动过。这个工具没有任何联网功能，文件由在本地处理、不上传文件的 worker 直接从你的硬盘读取。

- ✗ 不上传
- ✗ 不用注册
- ✗ 没有水印
- ✓ 能读 RAW
- ✓ 断网也能用
- ✓ 开源

## 怎么在浏览器里堆栈一组照片

1. **选帧。** 选一串连拍、间隔拍摄序列，或内含可用 JPEG 预览图的 RAW 文件。等文件全部打开。每一行都会显示找到的内容：RAW 会显示相机型号和内嵌预览图的实际尺寸。打不开的文件会留在列表里，方便你检查哪些被排除了。
2. **按你想失去的东西挑手法。** 噪点用平均值，想排除与其余不同的值就用 Sigma 裁剪。人、车或飞机用中位数，前提是它们在画面的每个位置出现的帧数不到一半。星轨用最亮，沿对焦环拍的微距用景深合成。菜单下面会说明手法和限制。
3. **决定要不要对齐。** 先用自动：测量平移、旋转和缩放，整张图中可靠区域一致时再校正透视。它适合广角星空。稳定的连拍用只平移可以减少测量。各帧已对齐，或要保留天空运动来制作星轨时，选不对齐。固定三脚架并不能让星星保持对齐。每帧都与标着基准的帧比较，默认是第一帧。“拿它当基准”只更换标记，不重排列表。
4. **读那四个数字，再按按钮。** 开始前，页面会显示计划结果尺寸、堆栈估计内存、堆栈计划解码次数，以及检查时读过的字节数。浏览器内部和内存回收可能需要建模缓冲区之外的内存，这些数字是计划，不保证浏览器的总用量。如果要分条，页面会建议降低工作分辨率。完成后按实际像素大小对比基准和结果，检查对齐详情，再下载。

## 说得更细的版本

[怎么堆栈照片来压噪点，或者把人去掉](https://abox.tools/zh/guides/stack-photos-to-reduce-noise/): 堆栈把一串连拍合成一张。用哪种手法，取决于你想失去什么：噪点、路人，还是微距那浅得可怜的景深。每种手法怎么运作、代价是什么，以及 RAW 文件在这里是什么位置。

## 工具箱里还有

- [图片涂黑与打码](https://abox.tools/zh/redact-image/): 你遮住的那块是从文件里删掉的，不是藏在文件里。
- [EXIF 查看与清除](https://abox.tools/zh/exif-editor/): 看看一张照片把你交代了多少，然后删掉。
- [DICOM 阅片器](https://abox.tools/zh/dicom-viewer/): CT、MR、X 光和超声，连窗宽窗位、头信息和测量一起。
- [图片转 ICO](https://abox.tools/zh/image-to-ico/): 进去一张图，出来的是浏览器、Windows 和 Mac 各自要的每一个尺寸。

## 常见问题

### 我的照片会被上传吗？

不会。每一帧的打开、解码、对齐、堆栈和写出，全都由你自己的浏览器在你自己的硬件上完成。这个工具没有任何联网功能，从不取东西，也从不发东西，页面的 `Content-Security-Policy` 里写着它能联系的每一个地址，没有一个属于本站。把页面加载一次，断网，它照样能用。这件事在这里比在多数工具上更要紧，单纯是因为量：二十个 RAW 帧差不多一个 G，而为了让别人算一次平均值就上传一个 G 的照片，正是这个工具存在的意义所要避开的事。

### 它能读哪些 RAW 格式？怎么读的？

CR2, CR3, NEF, NRW, ARW, SR2, SRF, DNG, ORF, RAF, RW2, PEF, SRW, 3FR, IIQ, DCR, KDC, MRW, MEF, RWL 等格式在文件内含可用 JPEG 预览图时受支持。工具会遍历目录，使用找到的最大预览图；它可能比传感器图像小，也可能根本不存在。**不解码传感器数据。**像素保留相机的白平衡和照片风格，每通道八位。请检查列表里的尺寸。检查读取量只统计文件头和目录，解码时还会读取 JPEG 片段。

### 那为什么不好好解码传感器数据？

解码传感器需要 LibRaw 或 dcraw 这样的 RAW 引擎，处理各相机专有的压缩方式。使用内嵌 JPEG 可以让工具保持小巧，并使用浏览器自己的图片解码器。代价是接受相机的渲染，以及文件里预览图的实际分辨率。要自行选择 RAW 冲洗设置，请先冲洗各帧，再导出 JPEG 或 PNG 来这里堆栈。

### 它能处理多少帧？多大的？

七种手法里有六种的累加器大小不随帧数增长。平均值、最亮、最暗、相加和景深合成每条处理一遍，Sigma 裁剪处理两遍。中位数保存当前条带内每一帧的数值，所以帧数越多，内存越大。任何手法的工作缓冲区超过工具预算时都可以分条，这就需要为每条重新解码各帧。页面会估计这些缓冲区，并显示堆栈计划解码次数。检查和对齐还会增加处理，浏览器编解码器和 GPU 内部可能需要估计之外的内存。

### 对齐到底做了什么？

工具测量每一帧相对基准帧的偏移，再以亚像素精度移回去。方法是相位相关：偏移表现为两张图片频谱之间的相位差，所以每张图一次傅里叶变换，就能用相同成本找到两百像素或两像素的偏移。旋转和缩放则用同样的方法在对数极坐标频谱中找出。自动还会测量分布在整张图上的区域，足够多的可靠测量一致时就校正透视。这有助于广角星空在边缘和中央都保持对齐。如果无法可靠测量额外修正，就保留旋转和缩放，并在对齐详情中说明未做透视校正。修正作用于整帧，不能对齐独立移动的物体，也不能让往旁边迈一步再拍的场景里所有深度都对齐。向左移的帧够不到右边缘，因此结果会裁到所有帧共同覆盖的范围，可能略小。这样可以避免未覆盖区域形成的暗边。

### 我该用哪种手法？

没有东西移动、只想消噪点时用**平均值**，独立的随机噪点大约按帧数的平方根降低。**中位数**用于移除在画面每个位置出现帧数不到一半的东西。**Sigma 裁剪**只对靠近平均值的数值取平均，排除超出所选阈值的值。帧数少或移动物体频繁出现时，它们可能留在结果里；如果去除它们最重要，中位数更可靠。星轨、烟花和光绘用**最亮**，移除移动的亮东西用**最暗**。**相加**把解码后的各帧做加法混合，处理的是八位图像值，并不能模拟相机更长的曝光。沿对焦环拍的微距用**景深合成**。

### 我的 RAW 是十四位的，为什么结果是八位？

RAW 输入用的是相机的 JPEG 预览图，输出是八位 PNG 或 JPEG。平均值和 Sigma 裁剪用更宽的累加器，只在最后取整，这样能从有噪点的各帧估计更干净的值，不用每一步都取整。保存后的图片仍是每通道八位，得不到线性传感器数据的位深或动态范围。

### 尺寸不同的帧，或者不同相机的帧，能堆吗？

能，但请确认是有意混用。最大的帧决定工作范围，其余各帧缩放后居中。保存的结果会裁到各帧共有的区域，所以形状不同或对齐可能让它比计划范围小。混用相机也会混合它们的色彩渲染。保持曝光和构图一致，并通过基准对比检查结果。

### 它说这一次会分条跑，什么意思？

该手法需要的工作内存超过工具愿意一次分配的量，因此图片会切成水平条带，一条一条堆栈。使用相同的对齐几何和堆栈手法，但浏览器重采样可能让最低位略有差异。每条都会重新读取各帧，所以更慢，页面会显示计划解码次数。工作分辨率降一档，内存变为四分之一，几乎总能变回一遍处理，注记会说明对应的设置。

### 为什么只有这个工具用 Worker，别的都不用？

因为只有它的活是按分钟算的。本站其他每一个工具做的事都是一两秒的量，把活挪出主线程只是走个过场。堆二十张大帧是在几百兆上做扎实的算术，放在主线程上就意味着一个卡死的页面：进度条不动，取消按钮不应，最后浏览器出来问要不要关掉这个标签页。Worker 是同一个浏览器里的第二条线程，跑的是同一个文件夹里的文件，受的是同一套策略。它不是服务器，也不是联网功能。

### 免费吗？要注册吗？

免费，没有账号、登录、试用期或水印。服务不对帧数或尺寸设额度。实际限制来自设备内存、浏览器的画布和解码器限制，以及处理时间。本站由广告支持，广告拿不到关于照片的信息。

## 这条隐私承诺怎么核实

- **处理在这个浏览器里完成。** 本工具在浏览器里处理输入和结果，处理代码不把它们上传去处理。Content-Security-Policy 限制可用资源和连接目的地，但已允许的主机仍可接收请求。策略不检查载荷，不能单独证明什么都没有发出。请把具体操作的请求与源码核对，或断网完成该本地操作。
- **RAW 预览图在这台设备上读取。** 很多相机 RAW 文件内含一张相机渲染的 JPEG 预览图。工具会遍历文件目录，取出最大的可用预览图。检查读取量只统计为找到和描述预览图而读过的文件头和目录；解码时还会读 JPEG 片段。传感器数据从不解码，列表会显示预览图的实际尺寸。
- **活是在这台机器的 Worker 里干的，不是在服务器上。** 堆栈可能需要几分钟，因此用 Worker 做运算，让页面继续响应、显示进度并接受取消。它是同一浏览器里的另一线程，见 `src/worker.js`。文件引用在本地交给它，不上传文件字节。Worker 的处理代码在设备上读取并合并文件；应检查这份源码，不能把页面的目的地策略当成 Worker 数据路径的证明。
- **关于这一组，没有向任何地方报告过什么。** 你堆了几帧、是哪台相机写的、每一帧偏了多少、你选了哪种手法、花了多久，这些都留在这一页的内存里，直到你关掉它。本仓库里没有任何一个自定义分析事件会带走其中一星半点，而本站在下载之后问的那一个问题，送出去的是一个大拇指的方向和工具的名字，别的什么都没有。
- **断网也能用。** 把网络断掉，这个工具一点不变，因为它里面从来就没有联网那一步。worker 和它加载的每一个模块都由这一页自己的 service worker 缓存着，所以装下来的那一份，拔了网线照样能堆 RAW 文件。

**你可以自己核对。**上面这些不用你信。这个页面是仓库里的模板和配置生成出来的，构建脚本你能读，也能自己跑一遍，跑出来的结果就提交在 `dist` 分支上。拿实际发给你的内容，跟你自己从源码构建出来的结果对一遍就知道了： https://github.com/A-Box-of-Tools/website

最值得先读的几个文件：`config/site.toml` 里是 Content-Security-Policy，`src/raw.js` 说明如何不解码传感器数据来找到 RAW 内嵌预览图；`src/stack.js` 是各手法的计算；`src/plan.js` 说明估计工作内存和堆栈计划解码次数。浏览器内部和内存回收可能需要建模缓冲区之外的额外内存。
