開發歷程:把監控攝影機的 DORI 計算搬進瀏覽器

這是 LocalPapa Notes 開發紀錄系列的第二篇。上一篇我們聊了開發順序中最早的 PDF 轉 Markdown;接著時間線往前走,下一個工具是 DORI 監控效能計算器

什麼是 DORI,為什麼有人需要算它

如果你規劃過監控系統,大概聽過 DORI。它是攝影機監控的國際標準(EN 62676-4),用「每公尺像素數(PPM, Pixels Per Meter)」來描述一台攝影機在某個距離上「看得多清楚」,分成四個層級:

  • Detection(偵測,約 25 PPM):那裡有沒有人?
  • Observation(觀察,約 63 PPM):他在做什麼?
  • Recognition(辨識,約 125 PPM):這個人我認得嗎?
  • Identification(識別,約 250 PPM):這到底是誰?

問題在於:一台攝影機能達到哪個層級,會隨距離改變。同一台機器,3 公尺處能「識別」人臉,到了 30 公尺可能只剩「偵測」——只知道有東西在動。

安防工程師在規劃佈點時,必須針對每個鏡頭、每段距離反覆套公式計算,確認「在這個距離還能不能辨識人臉」。這既繁瑣又容易算錯。

核心:一條公式,但要即時又直覺

換算本身不難,核心就一條公式:

像素密度 (PPM) = (解析度寬度 × 焦距) / (Sensor 寬度 × 距離)

反過來,要算「某個目標 PPM 的最大有效距離」:

最大距離 (m) = (解析度寬度 × 焦距) / (Sensor 寬度 × 目標 PPM)

難的不是數學,而是互動。工程師真正想要的,是手指一滑改個焦距、換個解析度,畫面上 D、O、R、I 四個極限距離就立刻跟著跳動——而不是按一次「計算」按鈕、看一個靜止的數字。

我們的做法

  1. 即時運算,無送出按鈕。 每個輸入欄位與下拉選單都綁上即時監聽器;任何參數一變,立刻重算 D / O / R / I 四個距離。把「填表 → 送出 → 看結果」的三步,壓成「邊調邊看」的一步。
  2. 常用規格做成 Preset。 焦距、Sensor 尺寸、解析度這些有業界常見值,做成下拉選單預設,讓工程師不必每次手敲。
  3. 統一精度。 所有距離四捨五入到小數點第一位——對現場規劃來說,0.1 公尺的精度剛好夠用,又不會給出一串假精確的小數。
  4. 附上原理說明。 工具裡放了 DORI 四層級的解釋,讓不熟標準的人也能看懂「125 PPM 到底代表什麼」。

當然,整個計算都在你的瀏覽器本地完成——不需要上傳任何案場圖或設備清單。

架構上的小決定

這個工具當時用的是平台的延遲載入(Lazy Load)架構:主程式只在使用者真正打開這個工具時,才去載入它專屬的邏輯與樣式。

為什麼要這樣?因為 LocalPapa 是一個有數十個工具的聚落。如果每個工具的程式碼都在首頁一次全部載入,首頁會越來越肥、越來越慢。延遲載入讓首頁保持秒開,而每個工具各自獨立、互不拖累。這個原則後來也一路延續下來。

學到的事

  • 「能算」和「好用」是兩回事。 公式人人會查,但把它變成一個邊調邊看、零等待的介面,才是真正幫工程師省時間的地方。
  • 預設值是一種體貼。 把業界常見規格做成 preset,等於把領域知識內建進工具,降低使用門檻。
  • 本地運算不只是隱私,也是速度。 沒有來回伺服器的延遲,「即時跟著跳動」才可能成立。

一以貫之的問題

跟系列第一篇一樣,這個工具回答的還是同一個問題:這件原本要靠人工、或丟給某個線上服務的事,能不能完全在瀏覽器裡、即時完成?

對 DORI 計算來說,答案再次是:可以。

下一篇開發紀錄,我們會走到 PDF 工具群的擴充——旋轉、PDF 轉圖片、解鎖。想追蹤系列?把 LocalPapa Notes 加入書籤吧。

Dev Log: Bringing Surveillance DORI Math into the Browser

This is the second post in the LocalPapa Notes dev-log series. Last time we covered the earliest tool in our history, PDF to Markdown. Moving forward along the timeline, the next tool is the DORI Surveillance Calculator.

What DORI is, and why anyone needs to compute it

If you've ever planned a CCTV system, you've probably heard of DORI. It's the international standard for surveillance camera performance (EN 62676-4), describing how clearly a camera "sees" at a given distance using PPM (Pixels Per Meter), in four tiers:

  • Detection (~25 PPM): is there a person there?
  • Observation (~63 PPM): what are they doing?
  • Recognition (~125 PPM): do I recognise this person?
  • Identification (~250 PPM): who exactly is this?

Here's the catch: which tier a camera achieves changes with distance. The same camera that can identify a face at 3 metres might only manage detection at 30 metres — you know something's moving, and that's it.

When laying out cameras, security engineers have to apply the formula over and over, for every lens and every distance, to confirm "can we still recognise a face at this range?" It's tedious and error-prone.

The core: one formula, but it has to be instant and intuitive

The conversion itself isn't hard. It comes down to one formula:

PPM = (resolution width × focal length) / (sensor width × distance)

And inversely, to find the maximum effective distance for a target PPM:

Max distance (m) = (resolution width × focal length) / (sensor width × target PPM)

The hard part isn't the maths — it's the interaction. What an engineer actually wants is to nudge the focal length or swap the resolution and watch the four limit distances (D, O, R, I) update immediately — not to press a "Calculate" button and stare at a frozen number.

How we did it

  1. Live computation, no submit button. Every input field and dropdown gets a real-time listener; the moment any parameter changes, all four D / O / R / I distances recompute. The three-step "fill form → submit → read result" collapses into a single "tweak and watch."
  2. Common specs as presets. Focal lengths, sensor sizes and resolutions have standard industry values, so we put them in dropdown presets — no re-typing every time.
  3. Consistent precision. All distances round to one decimal place — for on-site planning, 0.1 m is precise enough without spitting out a string of fake-precise decimals.
  4. Bundled explanation. The tool includes an explainer of the four DORI tiers, so even people unfamiliar with the standard understand what "125 PPM" actually means.

And of course, the whole calculation runs locally in your browser — no need to upload any site plans or equipment lists.

A small architectural decision

This tool used the platform's lazy-load architecture: the main app only fetches a tool's dedicated logic and styles when the user actually opens it.

Why? Because LocalPapa is a village of dozens of tools. If every tool's code loaded on the homepage at once, the homepage would get heavier and slower over time. Lazy-loading keeps the homepage opening instantly while each tool stays independent and doesn't drag the others down. That principle stuck around.

What we learned

  • "Can compute" and "pleasant to use" are different things. Anyone can look up a formula; the real time-saving is turning it into a zero-wait, tweak-and-watch interface.
  • Presets are a form of thoughtfulness. Baking common industry specs into dropdowns embeds domain knowledge into the tool and lowers the barrier to entry.
  • Local computation isn't only about privacy — it's about speed. Without the round-trip to a server, "updates instantly as you type" is even possible.

The same question, again

Like the first post in the series, this tool answers the same question: can something that used to require manual work — or handing it to some online service — be done entirely in the browser, instantly?

For DORI, the answer was, once again: yes.

In the next dev log, we move on to expanding the PDF suite — rotate, PDF-to-image, unlock. Want to follow the series? Bookmark LocalPapa Notes.

探索 39+ 個隱私優先的瀏覽器工具
全程本地運算、檔案不上傳。
前往 LocalPapa →
Explore 39+ privacy-first browser tools
Everything runs locally — your files never leave your device.
Visit LocalPapa →

想看英文版?點右上角 EN 切換語言。

Prefer Chinese? Tap at the top-right to switch.