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

@helping-ai-workflow/snapcode

v0.8.1

Published

檔案 ↔ 截圖友善色塊網格圖的無失真編解碼 CLI(編碼端純 stdlib)。node shim,需系統 python3 >= 3.9。

Readme

snapcode

檔案 ↔ 截圖友善色塊網格圖,無失真編解碼 CLI。任意檔案編碼成一張(或多張)色塊網格 PNG/終端 ANSI 圖,截圖(甚至印在螢幕上再重拍)就能解回原始位元組,並以 CRC32 逐 chunk 驗證一致性。

snapcode 是什麼

  • 編碼端:純 Python 標準庫(zlib + struct + 自帶 Reed-Solomon),不依賴 numpy / pillow / scipy,適合丟到無網路的遠端環境跑。
  • 解碼端:pillow + numpy + scipy,做定位方塊偵測、仿射校正、黑白/彩色電平 校準、erasure 標記與 Reed-Solomon 糾錯,容忍遮擋、旋轉、縮放、低解析度重拍。
  • 一張圖 = 一個資料方陣,3 個 L 形定位方塊嵌入方陣三個角(QR 式,非外掛 邊框)+ 1 格 separator 白環 + metadata(10 byte,含版本/尺寸/RS 參數;v0.7 起 以黑白散點從左上定位方塊漸疏放射、融入彩色場,取代舊的連續黑白塊)+ 資料格網,方陣外圍只留 2 格薄靜區(無獨立外框)。 單檔過大時自動切成多張,解碼端依檔頭的 file_id/idx/cnt 自動重組、缺塊即報錯。

版面配置(v0.5:嵌入式定位方塊)

v0.4 的定位方塊是掛在資料方陣「外面」的獨立邊框(quiet 4 格 + finder 7 格 + separator 1 格,四邊都要),v0.5 起改成 QR 碼式——3 個定位方塊直接嵌進方陣 左上/右上/左下三個角,右下角留給資料,靜區也從 4 格收到 2 格:

┌── quiet 2 格 ──────────────────────────────┐
│ ┌────┐░ ·metadata 散點·放射·      ┌────┐░   │
│ │ TL │░                          │ TR │░   │
│ │5×5 │░         資料格 …          │5×5 │░   │
│ └────┘░                          └────┘░   │
│ ┌────┐░                                    │
│ │ BL │░         資料格 …(右下角無定位方塊)│
│ │5×5 │░                                    │
│ └────┘░                                    │
└─────────────────────────────────────────────┘

= 1 格 separator 白環(定位方塊與資料格之間的緩衝,避免誤判邊界);quiet 只圍在整個方陣外圈一圈,不再另外疊加邊框。同一份資料下,v0.5 產出的 PNG 比 v0.4 明顯更小(實測面積省 ~25–50%,視資料量與長寬比而定,見〈容量表〉與 〈限制〉)。

v0.7 metadata 散點:metadata 從「左上一塊連續黑白方陣」改成從左上定位方塊 漸疏放射的孤立黑白散點(checkerboard 保證彼此不相鄰、離定位方塊留 moat), 融入彩色場、消除左上白斑,維持神秘感(看不出哪些格是 metadata)。同時 struct 由 16 byte 縮到 10 byte(散點 128→80),grid 再小一圈。散點座標由 (cols,rows) 以確定性整數演算法算出(encode/decode 兩端一致,屬格式契約);解碼端因散點位置 依賴 grid 尺寸,metadata 重試窗依 grid 大小自適應加寬以涵蓋非等向 cell 的估計誤差。

流程圖(文字版):

編碼:  原始檔案
          │ zlib 壓縮
          ▼
        切 chunk(依容量二分搜尋 chunk size)
          │ 加容器檔頭(檔名/長度/CRC32)
          ▼
        Reed-Solomon 編碼 + 確定性 interleave(置換抗連續遮擋)
          │
          ▼
        格網(metadata 區 + 資料區)→ PNG 或 ANSI half-block 印圖

解碼:  截圖 / 拍照
          │ 定位方陣三角嵌入的 3 個 L 形定位方塊 → 解仿射矩陣
          ▼
        讀 metadata 區(cols/rows/bits/RS 參數,CRC32 驗證)
          │
          ▼
        依仿射矩陣逐格取樣 → 黑白/彩色電平校準 → 最近色分類(超界標 erasure)
          │
          ▼
        deinterleave → Reed-Solomon 糾錯(erasure 優先,失敗退回盲糾)
          │
          ▼
        解容器檔頭 → 依 file_id/idx 重組多張 → CRC32 驗證 → 還原原始檔案

Quick start

pip install -e .
snapcode file.txt          # 編碼:在終端印出色塊圖(截圖用;預設不寫檔)
snapcode file.txt --png    # 編碼:改輸出 file.png 檔(不印終端)
snapcode 截圖.png          # 解碼:自動判向(PNG 且解得開 → 當 snapcode 圖解碼)

或用 npm 全域安裝(免 clone)

已上架 npm,一行安裝(需系統 python3 >= 3.9 在 PATH):

npm install -g @helping-ai-workflow/snapcode
snapcode file.txt          # 用法與上面完全相同

npm 版把純 Python 包 bundle 進套件,snapcode 指令透過系統 python3 執行—— 編碼端零額外安裝(純 stdlib,不下載任何 runtime)。要解碼截圖才需另裝三方庫:

pip install pillow numpy scipy

(解碼時若缺這些依賴,snapcode 會直接提示上面這行。)

其他旗標見下方〈CLI reference〉;安裝步驟以本節為準,其餘章節不重複。

資料夾

snapcode myproj/            # 打包整個資料夾 → myproj.png(大檔自動切多張)
snapcode myproj.png         # 還原出完整 myproj/(已存在則 myproj.1/)

打包預設跳過 .git / .svn / node_modules / __pycache__ / .venv / *.pyc 等; --all 連這些一起打。預估超過 10 張圖時會要求確認(--yes 跳過、給腳本用)。 symlink / 裝置檔會被跳過並印警告。還原時擋絕對路徑與 ../ 逃逸。

遠端部署(無網路)

編碼端零第三方依賴,可以把整支工具打包成單一 .py 檔丟到無網路的遠端機器:

snapcode --bundle --key <key> -o qr.py     # --key 省略時預設見 --help

產出的 qr.py 是 base64+zlib 內嵌五個模組 + loader 的單檔,已剝除註解、抹去 內部名稱,並以通行碼閘門保護 —— 純標準庫可執行,但第一個參數必須是通行碼:

python3 qr.py <key> <file>          # terminal 直接印出色塊圖,截圖回傳即可

通行碼錯誤或未提供時只印一行 usage: qr.py <mode> <file> 並以 exit 1 結束(不透露 需要通行碼、不透露工具身分),適合放在共用工作站避免他人誤用。--key 可自訂通行碼。

拿到印出的色塊圖後,直接截圖(螢幕四周有其他 UI 也沒關係),回傳截圖後在有安裝 decode extra 的機器上 snapcode 截圖.png 解回原始檔案。

qr.py 本身不支援再 --bundle(會直接報錯拒絕),需在完整安裝環境 (有原始 snapcode/*.py)執行 --bundle

CLI reference

snapcode [-h] [--zip] [--unzip] [-o OUT] [--bits {1,2,3,4,5,6}]
         [--scale SCALE] [--aspect ASPECT] [--max-cols MAX_COLS]
         [--ecc ECC] [--force] [--quiet] [--png] [--cli]
         [--bundle] [--key KEY] [--all] [--yes] [--version]
         [inputs ...]

| flag | 說明 | |---|---| | inputs | 檔案或 snapcode 圖(自動判向:PNG 且解得開 → 解碼,否則編碼) | | --zip | 強制編碼(即使輸入是可解的 snapcode PNG) | | --unzip | 強制解碼(不嗅探,解不開直接報錯) | | -o, --out | 編碼=輸出前綴(或目錄);解碼=輸出目錄 | | --bits {1,2,3,4,5,6} | 每格位元數(預設 6=64 色高密度,乾淨截圖用);要耐壓縮/遮擋改小,1=黑白最穩 | | --scale | PNG 每格像素(預設 6);截圖後解析度不足時建議調大 | | --aspect | 長寬比 寬:高(預設 16:9) | | --max-cols | 單張最大格寬(預設 240);超過容量自動切成多張 | | --ecc | 每 255 byte 的 Reed-Solomon 糾錯位元組數(預設 24) | | --force | 解碼輸出允許覆蓋同名檔(否則自動加 .1 .2 … 後綴) | | --quiet | 靜音進度訊息(仍會印色塊圖,除非重導向) | | --png | 編碼時輸出 PNG 檔,不在終端印色塊圖 | | --cli | 編碼時在終端印色塊圖(預設行為,不寫 PNG 檔) | | --bundle | 輸出 stdlib-only 單檔編碼器(見〈遠端部署〉),-o 指定輸出檔名(預設 qr.py) | | --key | bundle 通行碼;產物需 python3 qr.py <key> <file>(預設見 --help) | | --all | 資料夾打包含 .git/node_modules 等跳過清單項目 | | --yes | 跳過資料夾 >10 張圖的確認提示 | | --version, -v | 顯示版本 |

--zip--unzip 互斥;--png--cli 互斥;--ecc 需在 2..100 之間; 混合輸入(同批既有要編碼又有要解碼的檔)搭配 -o 時語意不明,會直接報錯,請分開跑。

bits 5/6 高密度說明

--bits 每增加 1,每格可表示的顏色數翻倍(--bits 4=16 色、--bits 5=32 色、 --bits 6=64 色),格數不變下圖能塞進更多資料、成品也更小張。但 bits 5 與 bits 6 的最小色距實測相同(都是同一批 lattice 調色盤在 32/64 點下的必然結果, 並非 bits 5 比 bits 6 更疏、更耐雜訊)——色距本身隨 bits 增加而變薄,分類容錯 隨之降低。因此 --bits 5/--bits 6 定位在乾淨截圖的高密度傳輸(螢幕截圖 直接貼、無二次壓縮);預設即為 --bits 6。若傳輸路徑會經 JPEG 或其他有損 壓縮(LINE/Messenger 等)、或截圖可能被部分遮擋,請改用更低的 --bits--bits 1 黑白最穩、色距最大;23 次之)——bits 越低格數越多,單格色距 更大、容錯更寬裕。(--bits 4 的 16 色手調色盤實測色距反而是全部 bits 中最窄的,不適合當耐壓縮首選,勿誤用。)

容量表

單張圖在預設 RS 糾錯(--ecc 24)與 16:9 長寬比下,扣除 RS 冗余與容器檔頭 (約 40 byte)後,zlib 壓縮可用 payload 位元組數(近似值;文字檔/原始碼 等可壓縮性高的內容,zlib 壓縮前的原始檔案可再大上數倍):

| --max-cols | --bits 1 | --bits 2 | --bits 3 | --bits 4 | --bits 5 | --bits 6 | |---:|---:|---:|---:|---:|---:|---:| | 120 | 864 B | 1,765 B | 2,665 B | 3,566 B | 4,466 B | 5,367 B | | 240(預設) | 3,606 B | 7,249 B | 10,891 B | 14,534 B | 18,200 B | 21,843 B | | 360 | 8,166 B | 16,369 B | 24,595 B | 32,798 B | 41,024 B | 49,227 B |

(v0.5 起 3 個定位方塊嵌入方陣本體佔約 108 格;v0.7 起 metadata 由連續塊 128 格 改散點 80 格,reserved 共約 188 格。因為外圍不再疊加獨立邊框、metadata 又縮小, 同一份資料實際需要的 PNG 尺寸明顯縮小——真正的容量收益要看「同資料所需圖檔 面積」而非這張固定 --max-cols 對照表,見下方〈限制〉。)

超過單張容量時,snapcode 自動切成多張圖(檔名附 .NNN.png 序號),解碼端依 file_id/idx/cnt 自動重組,缺任一張會直接報錯要求補齊。

限制

v0.5 把定位方塊從資料方陣外的獨立邊框改成嵌入方陣三角(見〈版面配置〉), 靜區也從 4 格收到 2 格——同一份資料所需的 PNG 面積因此明顯縮小(實測約省 25–50%,視資料量與長寬比而定),且這個瘦身沒有拿 robustness 交換:旋轉 ±5°、縮放 0.5×–2.4×、JPEG 品質 55 以上、局部遮擋、terminal 截圖(含行距造成 的縫隙、非等向字元格)等劣化通道,v0.5 的嵌入式版面實測結果與 v0.4 外框式 版面相同(皆全綠,見 tests/test_robustness.py)——不是「乾淨截圖限定」, 放心用在會經過壓縮或手機拍照的傳輸路徑。

真正的取捨在別處:在固定 --max-cols 下,因為定位方塊現在直接佔用方陣 內的資料格(而不是像 v0.4 那樣掛在外面不吃格),可用 payload 比 v0.4 略降 ~1.5%(見上方容量表附註);要耐雜訊/劣化仍建議用較低 --bits--bits 1 色距最大最穩),與 v0.4 的建議一致,並未因嵌入式版面改變。

螢幕解析度注意事項

  • 建議每格像素(cellpix,取決於截圖時的顯示尺寸而非 --scale)維持 ≥ 3 px, 低於此值 finder 偵測與電平校準容易失敗;decode_image 對第一趟失敗會自動 Lanczos ×2 放大重試一次,但仍以原圖夠大最可靠。
  • 1080p 螢幕建議 --max-cols 240 以內、--scale 6 起跳;4K 螢幕可以放大到 --max-cols 360+更高 --scale,或維持同容量換取更粗的格線(抗遮擋/抗模糊)。
  • snapcode file 在終端印圖時,若行寬不足會提示「終端寬度不足」;縮小字體 (或加大終端視窗)讓一整行塞得下,再重新執行。
  • 截圖時周圍夾雜其他視窗 UI 沒關係,定位方塊偵測會自動排除雜訊聚焦到色塊圖本體; 但不要用有損通訊軟體(LINE/Messenger 等)二次壓縮傳輸再截圖——不過實測 JPEG 品質 55 以上仍可正常解碼,品質更低則不保證。

疑難排解

| 錯誤訊息 | 常見原因 | 對策 | |---|---|---| | 找不到定位方塊 | 截圖裁切到定位方塊、圖太小/太模糊、或前景另有大片深色區塊干擾 | 把截圖裁到色塊圖本體附近重試;用更大 --scale 重新產圖 | | metadata 讀取失敗 | 截圖被過度縮小、metadata 區被裁到或被遮擋 | 確認截圖含完整色塊圖四角;用更大 --scale/原始解析度截圖 | | Reed-Solomon 糾錯失敗,損壞過多 | 遮擋/雜訊超過 --ecc 糾錯上限 | 用更大的 --ecc 重新編碼;或換用 --bits 1(黑白對雜訊最穩) | | 截終端機圖解不開,PNG 卻可以 | 終端 line-spacing(行距)> 1.0 時,行間縫隙會切斷定位方塊(深/淺色主題縫皆未支援) | 把終端 line-spacing 調回 1.0 再截圖;或改截 PNG 檔 |

開發

測試:

pytest tests/

模組職責:

| 模組 | 職責 | |---|---| | snapcode/codec.py | 容器格式(SC v1)、置換/interleave、bit↔symbol、encode_file/reassemble — 純 stdlib | | snapcode/layout.py | 版面幾何、調色盤、metadata 編解碼、build_grid/build_canvas — 純 stdlib | | snapcode/render.py | 手寫 PNG writer、ANSI half-block 印圖 — 純 stdlib | | snapcode/_reedsolo.py | vendored Reed-Solomon(見 NOTICE)— 純 stdlib | | snapcode/detect.py | 解碼端:定位方塊偵測、仿射校正、電平校準、分類、RS 還原(需 pillow/numpy/scipy) | | snapcode/cli.py | 參數解析、方向嗅探、檔名安全、--bundle 單檔打包 |

tests/helpers.py 提供測試共用的 encode_pngs(產多張 PNG)與 parse_ansi (把 ANSI 輸出解析回格網索引),避免各測試檔各自重寫。