---
name: Dirty Pixels
slug: dirty-pixels
category: Automation
description: Dirty Pixels重画输入图片为黑底像素粒子画，并可输出静态PNG或无缝循环GIF/MP4。适合把照片或插画转换成带流动笔触和尘化质感的粒子风格。
github: "https://github.com/haorantang97/LabArt/tree/main/plugins/dirty-pixels/skills/dirty-pixels"
language: Python
stars: 282
forks: 16
install: "npx degit https://github.com/haorantang97/LabArt/tree/main/plugins/dirty-pixels/skills/dirty-pixels ~/.claude/skills/dirty-pixels"
installs_to: ~/.claude/skills/dirty-pixels
source_path: plugins/dirty-pixels/skills/dirty-pixels/SKILL.md
collection_size: 2
category_size: 1754
collection_url: "https://dirskills.com/collections/haorantang97/LabArt"
added: 2026-09-03T06:03:38.639Z
last_synced: 2026-09-03T06:03:38.639Z
canonical_url: "https://dirskills.com/skills/dirty-pixels"
---

# Dirty Pixels

Dirty Pixels重画输入图片为黑底像素粒子画，并可输出静态PNG或无缝循环GIF/MP4。适合把照片或插画转换成带流动笔触和尘化质感的粒子风格。

**Install:**

```bash
npx degit https://github.com/haorantang97/LabArt/tree/main/plugins/dirty-pixels/skills/dirty-pixels ~/.claude/skills/dirty-pixels
```

## README

# Dirty Pixels v5

把一张图**重画**成黑底像素粒子画。核心脚本 `scripts/dirty_pixels.py`，确定性（同参数
同 seed 逐字节相同），全部美学决定都是参数。**给用户交付时必须报出完整命令**——那就是版本号。

## v5 与旧版的关系（先读这段，别走回头路）

v4 的「实心网点 mass 层 + 规划蒙版」画法在实践中被否决：蒙版是画出来的几何形状，
边界永远贴不住图像；对连续光影塑形的图，mass 层会把层次压成色块。
**v5 的正典是纯粒子**：不给 `--plan`，不开 mass 层，每一笔的落点由原图亮度和梯度采样，
边界天然贴合。虚空靠 `--floor` 从亮度上切，不靠蒙版圈。
（v4 的 `--plan`/`--mass` 仍可用，仅当输入是平实大色块、真需要静止锚定层时才考虑。）

## 正典配方（与用户逐轮审定的终版）

```bash
python3 scripts/dirty_pixels.py in.png -o out \
  --preset detail --simplify 1 --size 1400 --seed 305 \
  --sparsity 1.8 --gamma 2.4 --edge 0.7 --density 1.5 --floor 0.035 \
  --stroke 20 --curve 0.03 --jitter 0.02 --coherence 45 \
  --length-mix 3 --aniso-len 1.5 --fray 1.4 --gap 0.22 \
  --flow 5 --boil 0.35 --trail 1 --conserve 1.5 \
  --burst-at X,Y,0.55 --rain 0.4 --rain-angle 92 --rain-speed 2 \
  <按物理规划的方向参数，见下> \
  --seconds 1.6 --fps 12 --mp4
```

`--floor` 是唯一必须按图调的：极暗原图（平均亮度 <0.05）用 0.03–0.05；
正常亮度原图从 0.2 起试。虚空不够往上提，主体开始碎往下降。

## 笔触质感的四根支柱（每根都是用户实测选定的）

1. **长短混搭 `--length-mix 3`**：幂律长度分布——大多数是斑点，少数抽成长线。
   短的负责图像信息，长的负责运动感。均匀分布（=1）会满屏中长线，画面发"土"。
2. **内容决定长度 `--aniso-len 1.5`**：方向性强的地方（手臂、浪面、光柱）才允许长线，
   各向同性的细节区只出斑点。清晰度靠内容恢复，不靠全局调短。
3. **错位 `--fray 1.4 --gap 0.22`**：每根笔拆成随机长度的子段，逐段横向偏移、随机丢弃、
   亮度不一。一根"线"其实是几截没对齐的短段——这是"脏"/数据错误感的来源。
   干净的连续线（fray 0）一眼就是机器画的。
4. **几乎直 `--curve 0.03 --jitter 0.02`**：curve 高了长笔会卷成逗号钩；0 又太机械。

## 流动：三条铁律

**① `--stroke` 长度、方向场、真实位移缺一不可。** flow<2 是原地闪烁（虫子爬），
正典 flow=5：一个循环净位移约 40 输出像素，肉眼能读出"划过"。
`--trail 1` 让笔触沿运动方向拖尾（自带运动模糊）。

**② 集体同向靠 `--coherence`。** 它决定方向场跟多大尺度的结构：2.5 = 每个像素各走各的
（错），45 = 一整块（整条手臂、整片浪面）同向流动（正典）。要跟到手指级细节降到 20–30。

**③ 方向的"往哪头"必须按物理规划，见下节。** 结构张量给的是无符号线场，
只回答"沿哪条线"，不回答"往哪头"——后者是内容决策，不是数学。

## 动效规划：先读图，再定方向（核心方法论）

**流程**：列出画面元素 → 逐个问"这东西在物理上往哪走" → 一个元素一条参数。
一个全局角度必然在某处是错的（光柱下坠 vs 余烬上升不可能同一个方向）。

| 画面里的东西 | 物理 | 参数 |
| --- | --- | --- |
| 光柱、雨、瀑布、坠落物 | 下坠 | `--flow-region X,Y,RX,RY,90` |
| 火焰、余烬、烟、气泡 | 上升 | `--flow-region ...,-90` |
| 破碎浪的浪背 | 爬升翻出 | `--flow-region ...,-40` 左右 |
| 海面/前景水 | 随破碎方向推 | `--flow-region ...,0 或 180` |
| 爆炸、被光推开的尘 | 由中心向外 | `--flow-from-burst` |
| 风中的旗、发、草 | 顺风 | 风向角度 |
| 天然同心结构（发髻、年轮、浪的卷桶、旋涡星系） | 旋转 | `--swirl X,Y,±S,R` |

三层模块，独立、可局部使用：
- `--flow-bias 角度` / `--flow-from-burst`：全局兜底，只在整图有压倒性方向时单用
- `--flow-region X,Y,RX,RY,ANGLE[,S]`：**默认手段**，软椭圆分区，可重复，覆盖全局，
  只改"往哪头"不改场的几何
- `--swirl X,Y[,S[,R]]`：改场的几何造真环流。**只给天然同心的结构**（参考：原作者的
  佛像只在螺发上用漩涡，主体不用）。判据：这块结构本身是不是同心的？强度 0.4–0.5 =
  暗示，0.85+ = 整块卷入（会吞掉形体性格）。正负号 = 转向。

**渲染后必须逐区验证方向**（方向反了在静帧上看不出来）：

```python
from numpy.fft import rfft2, irfft2
def shift(a, b):   # 两帧同位置裁片的整体位移；dy>0 = 向下
    A=a-a.mean(); B=b-b.mean()
    c=irfft2(rfft2(B)*np.conj(rfft2(A)), A.shape)
    p=np.unravel_index(np.argmax(c), c.shape)
    return (p[1]-(a.shape[1] if p[1]>a.shape[1]//2 else 0),
            p[0]-(a.shape[0] if p[0]>a.shape[0]//2 else 0))
```

## 吸引子假轮廓与 `--conserve`（必开）

平滑矢量场推进粒子，粒子会压缩到场的**吸引曲线**上，形成蚯蚓状的亮线。这些曲线属于
场的拓扑，不属于画面里的任何东西——看起来像轮廓，却勾不出任何形状，是这个算法最典型的
视觉 bug。`--conserve 1.5` 做密度守恒：每帧对比粒子当前分布与出生分布，哪里挤了 N 倍
就把亮度除回 N 倍，压缩被精确抵消，其余像素不受影响。**正典必开。**

注意：这种线**不饱和也看得见**（它是密度聚集不是亮度过曝），所以验收要看画面，
不能只看饱和像素指标。历史上 `--declump/--ink/--soften/--contour` 都是治标方案，
参数还在但默认关，不要再用它们来治这个问题。

## 调参必须用动画帧，不能用静帧

`--static-only` 时 frames=1，粒子完全不推进——凡是涉及 flow/boil/conserve 的调参，
静帧全部一样，必须渲动画看。静帧只能用来审构图和笔触质感。

## 内存

1400px 方图在 3× 超采样下是 4200×4200，**方图别和其他图并行渲染**（8GB 容器会 OOM）。
宽图三张并行安全。

## 自检清单（每次交付前）

- 循环无缝：|末帧−首帧| ≈ 相邻帧差（比值 0.95–1.05）
- 构图稳：相邻帧大尺度密度相关性 > 0.985
- 方向对：逐区 shift() 位移与物理判断一致
- 无蚯蚓线：肉眼查大面积密集区（地面带、浪身）有无意义不明的亮曲线
- 虚空 ≥ 60%（纯粒子画法下典型 80–90%）

## 常见失败

- **虫子爬（原地抖不流动）**：flow 太小或 boil 压过 flow → flow 5 / boil ≤0.5。
- **长线像梳过的头发（太规整）**：fray=0 → 开 1.4；还整齐就查 length-mix 是不是 1。
- **长笔卷成逗号钩**：curve 太大 → 0.03。
- **蚯蚓状意义不明亮线**：conserve 没开 → 1.5（网格细、强度别超 2，2.5 起画面压平）。
- **光柱向上流 / 方向违反物理**：用了全局 flow-bias 兜所有区 → 逐元素 `--flow-region`。
- **满屏中长线发土**：length-mix=1 → 3；density 同步降到 1.5 以下。
- **画面太密失去留黑**：floor 提高；density 降；sparsity 提到 2。
- **GIF 在 macOS 预览不动**：正常，拖浏览器看。
- **两次输出不一样**：参数或 seed 变了；算法本身确定性。

## 边界与伦理

细节（五官、文字、小窗）必然消失；平缓明暗过渡会变均匀绒毛。适合"一个大形 + 强对比"。
本 skill 是对该美学的算法化致敬，代码全部原创；风格不受版权保护，但不得以原作者名义
署名或宣传。转换全在本地完成。
