Skip to content

About

A Chrome extension that translates Kindle Cloud Reader books in place with Claude.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

77 Commits

Folders and files

Repository files navigation

繁體中文 | English

Kindle 自動翻譯(Chrome extension)

Tests

讀取 Kindle Cloud Reader(read.amazon.com 等)自己的頁面資料,知道畫面上是哪一頁、哪些字是同一段,用本機 OCR(Tesseract)辨識文字,再交給 Claude Haiku 翻譯、Sonnet 校對成繁體中文。譯文直接蓋在書頁原文的位置上,也同時顯示在 Chrome 側邊欄。讀目前這一頁時,下一頁會先翻好,翻過去就直接出現。

範例:《Build a Reasoning Model (From Scratch)》雙頁版面,內文和圖說的譯文蓋在原文位置上,圖 1.1、1.2 保留原圖,右側是側邊欄

照順序往後讀時,第二頁起翻頁就直接看到譯文;第一頁、跳頁或往回翻到沒翻過的頁,要等 10~15 秒。覆蓋層沒出現時,側邊欄狀態列會用紅字顯示原因,底下的執行紀錄可以看到每一步。

用閱讀器自己的頁面資料

Kindle Cloud Reader 把書頁畫成圖片,但畫之前,它先向 Amazon 拿了一份頁面資料:每一行字的位置、字型、顏色、屬於哪一段,插圖在哪裡,以及字形的輪廓。2.0 起,擴充功能旁聽這份資料(不另外向 Amazon 要任何東西),用它來做三件事:

  • 知道畫面上是哪一頁:照資料把候選的頁畫出來,跟閱讀器顯示的圖逐像素比對,插圖以外完全一樣的就是這一頁。工具列、游標、彈出的選單都不會被誤認成翻頁。
  • 知道哪些字是同一段、哪個是標題、哪裡是插圖:直接來自書本身的排版,不用猜。插圖裡的字不翻譯,原圖照樣露出來。
  • 給 OCR 一張乾淨的頁面:沒有工具列、游標和譯文殘影。字形在資料裡只有編號、沒有文字,所以內容還是要由 Tesseract 辨識。

譯文以段落為單位存起來,用的是該段在書中的位置,跟字級、視窗大小無關:改了字級或視窗大小,讀過的段落不用重翻。

1.x 用截圖、粗略的畫面指紋和 DocLayout-YOLO 版面模型(WebGPU,75 MB)做這些事,2.0 全部換掉了,也不再需要 WebGPU 和下載模型。

安裝

  1. 從 Releases 下載 kindle-translate.zip。
  2. 解壓縮 kindle-translate.zip,得到 kindle-translate 資料夾。
  3. Chrome 網址列輸入 chrome://extensions,打開右上角「開發人員模式」。
  4. 按「載入未封裝項目」,選 kindle-translate 資料夾。
  5. 在擴充功能的「詳細資料 → 擴充功能選項」填入 Anthropic API key(console.anthropic.com 建立),按儲存。

使用

  1. 打開 Kindle Cloud Reader 並開啟一本書。
  2. 點工具列上的擴充功能圖示,打開側邊欄。
  3. 按「翻譯這一頁」,或按 Alt+T。勾選「翻頁自動翻譯」時,翻到沒翻過的頁、停留約 1 秒就會自動翻譯;翻過的頁直接顯示。目前這一頁的譯文已經畫上時,按鈕會變成「重新翻譯本頁」,按下去會略過快取重新請求。
  4. 譯文會蓋在書頁原本的段落上(字級自動縮放、底色配合閱讀器主題)。側邊欄上方的「書頁顯示:譯文|原文」切換鈕,或書頁右下角的「顯示原文/顯示譯文」小按鈕,或按 Alt+O,都可以隨時切換,切回譯文時會立刻顯示,不用重新翻譯。翻頁時覆蓋層會先清掉,等新的一頁翻好再出現。
  5. 側邊欄最上方是最新一頁的譯文,可以按「複製」。

運作方式與注意事項

  • 只有側邊欄開著時才會自動翻譯,避免背景偷偷花費 API 額度。
  • 打開書之後才載入擴充功能(或重新載入擴充功能)的分頁,要等閱讀器拿下一批頁面資料才認得出目前是哪一頁;側邊欄會提示,重新整理 Kindle 分頁最快。
  • 翻頁後停約 1.2 秒才會送出翻譯,快速連續翻頁時中間的頁面不會送出。翻譯途中換頁的話,那一頁會在背景翻完並存進快取(最多同時一頁,再多就取消最早的),同時開始翻新的一頁;翻回還在翻的頁時會等它完成,不會重送。快取在關掉瀏覽器時清除。
  • 預先翻譯下一頁(設定頁,預設開啟):目前這一頁的譯文畫上、停留約 2 秒後,就先把下一頁翻好。照順序往後讀時不會多花;停止閱讀、跳頁或往回翻時,預先翻好但沒讀到的頁照樣計費。只用於翻譯方式 1、2。
  • 校對時參考前面的頁(設定頁,實驗,預設關閉):精修模式的 Sonnet 校對時,一併送上同一本書在這一頁之前讀過的段落(原文和定稿的譯文),統一人名、用語和語氣。另外每本書記一份人名對照表(英文原名 → 譯名),由 Sonnet 校對時整理,之後每次翻譯和校對都照它翻人名,隔了再多頁也一樣;已經記下的譯名不會被改掉。開啟後,畫上去的段落(原文和譯文)和人名對照表會存在這台電腦的 Chrome 本機儲存區,段落保留 1 週、人名保留 30 天,設定頁可以一鍵刪除。參考段落的上限預設 16000 tokens(雙頁約 4–5 個畫面),用 prompt caching 降低成本:連續閱讀時每頁約多 1.3 美分,休息超過 5 分鐘後的第一頁約多 4 美分。只會送出這一頁之前的內容,不會送出還沒讀到的部分。
  • 設定頁的「翻譯方式」有三種:
    • 1. 快速:Tesseract.js 在瀏覽器裡辨識每一欄的文字,依閱讀器的頁面資料分成段落,只把文字送給 Claude Haiku 5.5 翻譯;雙頁時左右兩欄同時送出。每頁約 0.1 美分,書頁圖片不會離開電腦。目前只載入英文辨識模型。
    • 2. 精修(預設):同 1,Haiku 翻完後再由 Sonnet 5.5 整頁校對一次,Sonnet 只回傳需要修改的段落,修改內容會列在側邊欄的執行紀錄裡。每頁約 1 美分。
    • 1、2 偶爾會有某一欄被以版權為由拒絕翻譯,那一欄會自動改用 Opus 5.5 翻譯文字(不再校對)。
    • 3. 看圖:截圖直接送給 Claude Opus 5.5,由它找段落位置並翻譯,可以處理非英文書。每頁 20 秒以上,effort 預設 low,不預先翻譯下一頁。實測 Sonnet 5.5、Haiku 5.5 看書頁截圖會以版權為由拒絕,所以這個模式只用 Opus。Opus 5.5 被安全分類器擋下時,會依序改用 Opus 5、Opus 4.8 重試。截圖會先縮到長邊 2576px 且總像素 3.7MP 以內再送出,超過的話 API 會再縮一次,座標就對不上。
  • 只會連到 api.anthropic.com。API key 存在 Chrome 同步儲存區。閱讀器的頁面資料只在頁面裡用來辨識和畫出這一頁、下一頁,不會送出去。
  • Claude 偶爾會以版權為由只給摘要。偵測到摘要會自動重新請求一次;仍是摘要就照樣顯示並標示「摘要」,但不存快取。
  • 位置以段落為單位,不是逐行對齊;一段從左頁接到右頁時,譯文依行數分成兩塊。
  • 原文的斜體字,譯文用楷體;段落裡的粗體字照樣是粗體;書頁上的螢光標記,譯文裡對應的字也用同樣的顏色標出來。看圖模式不支援。
  • 譯文方框會蓋住底下的原文。要畫新的螢光標記時,先切到「原文」(右下角按鈕或 Alt+O),選取文字畫好標記,再切回「譯文」,那一段會照新的標記重翻。
  • 依賴 Kindle Cloud Reader 沒有公開的頁面資料格式;Amazon 改了格式,擴充功能就會認不出頁面,側邊欄會顯示原因。
  • 這是逐頁翻譯給自己閱讀用,不要拿來大量匯出書本內容,那會違反 Amazon 使用條款。

版本紀錄

  • 2.3.2:有書名底線的頁(閱讀器畫的一般底線,不是連結的)不再出現「閱讀器的頁面資料裡找不到目前這一頁」;比對差一點點、但明顯是某一頁時也認得出來,記錄會註明。認不出來時,記錄多一行「辨識不到:…」說明原因。
  • 2.3.1:Claude 只給摘要的頁,校對回報的人名不再存進對照表(跟段落快取一樣,摘要不存);重試後拿到正常翻譯時,只存那一次的人名。
  • 2.3.0:人名對照表。
    • 開啟「校對時參考前面的頁」時,每本書記一份人名對照表(英文原名 → 譯名),由 Sonnet 校對時整理,之後翻譯(包括改由 Opus 補翻的那一欄)和校對都照它翻人名,隔了再多頁也一樣;這時 Opus 補翻的那一欄也會送 Sonnet 校對。已經記下的譯名不會被改掉,每個名字最後一次出現後保留 30 天,設定頁可以刪除。
    • 修正連續讀約 30 頁後每頁都翻譯失敗(Chrome 的 session 儲存空間滿了):滿了就丟掉較舊的一半快取。
  • 2.2.0:校對時參考前面的頁。
    • 新增「校對時參考前面的頁」(實驗,預設關閉):Sonnet 校對時參考同一本書前面讀過的段落,統一人名、用語和語氣。參考段落存在本機 1 週,設定頁可以刪除。
    • 精修模式改成兩欄都翻完後整頁校對一次,不再每欄各校對一次。
    • 執行紀錄列出 prompt caching 的快取讀寫量。
  • 2.1.0:保留原文的文字樣式與螢光標記。
    • 原文的斜體字,譯文用楷體;段落裡的粗體字照樣是粗體。
    • 書頁上的螢光標記,譯文裡對應的字也用同樣的顏色標出來;加、刪標記時只重翻那一段。
  • 2.0.2:
    • 修正有灰底提示框或連結的頁認不出來(例如技術書):照頁面資料畫出灰底,比對時不比方框邊緣和連結底線。
    • 譯文不再蓋住閱讀器的工具列和設定面板。
  • 2.0.1:修正 2.0.0 的問題。
    • 某一頁正在翻譯時按「翻譯這一頁」,改成等它翻完,不再取消重送、重複付費。
    • Claude 判斷是雜訊而留白的段落也存進快取,翻回來或預讀時不再重問。
    • 快速連續翻頁時,不再把已經翻過去的頁畫上去或送到側邊欄,也不再跳出紅字警告。
    • 閱讀器回傳空的頁面資料時不再出錯;執行紀錄「比對了幾個畫面」只算真的比對過的。
  • 2.0.0:改用閱讀器自己的頁面資料,並預先翻譯下一頁。
    • 旁聽閱讀器拿的頁面資料,照它把頁面畫出來,跟畫面逐像素比對,精確知道目前是哪一頁;不再截圖比指紋,工具列、游標不會再被當成翻頁。
    • 段落、標題、插圖直接來自頁面資料,拿掉 DocLayout-YOLO 版面模型:不再需要 WebGPU,也不用下載 75 MB 的模型。
    • OCR 讀的是照資料畫出的乾淨頁面;譯文方框照原文的實際位置擺放,底色和字色來自閱讀器的主題。
    • 譯文以段落為單位快取,改字級、視窗大小或翻回來都不用重翻讀過的段落;翻譯途中換頁的結果也不浪費。
    • 新增「預先翻譯下一頁」(預設開啟)。
    • 側邊欄的「存下截圖」改成「存下頁面資料」(除錯用)。
  • 1.1.0:OCR 只讀 Kindle 畫書頁的範圍。
    • 位置由頁面回報,不再用固定比例。以前高的視窗會切掉章名和第一行,矮的視窗又會讀進標題列;現在不論視窗大小、縮放比例、螢幕解析度都一樣準。
    • 判斷「同一頁」也改看同一個範圍,工具列滑進滑出不再被當成翻頁。
    • 「存下截圖」會另外存一個 .json,記錄書頁的位置,給測試用。
    • 設定頁新增「開發者」區塊,可以讓測試工具觸發截圖(預設關閉)。
    • 修正背景程式搶先用空值回覆頁面的訊息。
  • 1.0.1:判斷「同一頁」的門檻從 8% 放寬到 15%,畫面小變動不再被當成翻頁。側邊欄執行紀錄新增「存下截圖」,把目前畫面存成測試用的截圖。模型下載失敗重試時,進度從 0 重新顯示。
  • 1.0.0:用 DocLayout-YOLO 版面模型(WebGPU)判斷段落、標題、圖說、圖、表,取代原本靠縮排、行距、字距猜的規則;圖、表、公式裡的文字保留原文。模型第一次使用時下載(75 MB)並存在瀏覽器裡;無法使用時明確報錯,不改用別的方式。側邊欄新增模型狀態列。
  • 0.6.3:翻譯方式預設改成「2. 精修」(Haiku 翻譯、Sonnet 校對)。
  • 0.6.2:修正譯文常常變回英文、停在英文不回來。
    • 判斷是否同一頁改用粗略指紋(大致相同就算同一頁),工具列、滑鼠效果、JPEG 雜訊不再被當成換頁。
    • 清掉譯文後等畫面真的重畫才截圖,不再截到殘留的譯文、讓 OCR 讀成亂碼。
    • 背景程式閒置被 Chrome 停掉後,第一個翻頁訊息不再被丟掉。
    • 工具列出現或收起時觸發的 resize 不再清掉譯文;重新載入擴充功能後,舊的書頁程式不再干擾。
    • 執行紀錄會顯示每次比對的差異百分比,並自動捲到最新一行,也同步印在 Kindle 分頁的 console。
  • 0.6.1
    • 翻譯途中換頁時,舊的那頁改在背景翻完並存快取,不再取消;翻回去時直接顯示。
    • 重新載入擴充功能後,已開著的 Kindle 分頁會自動接上,不用重新整理。
    • 修正靠左對齊的圖說最後一行偶爾被切成另一段、沒有蓋上譯文。
  • 0.6.0
    • OCR 模式略過圖表,不再把圖裡的標籤翻成一團蓋在圖上;兩行的大標題、靠左對齊的圖說不再被切成好幾段。
    • 新增 Alt+O 快捷鍵切換譯文/原文。
    • 重新載入擴充功能後,書頁上不再殘留舊的按鈕和覆蓋層。
  • 0.5.1
    • 設定頁合併成一個「翻譯方式」選單:1. 快速、2. 精修、3. 看圖。
    • 精修模式會在執行紀錄列出 Sonnet 每一段的修改。
    • 放大右下角的切換按鈕。
  • 0.5.0:新增「Haiku 翻譯、Sonnet 校對」的精修模式。
  • 0.4.3:書頁右下角加回「顯示原文/顯示譯文」按鈕;翻譯模型預設改回 Haiku。
  • 0.4.2:翻譯模型預設改成 Sonnet,可在設定頁改回 Haiku。
  • 0.4.1:側邊欄的「譯文|原文」切換鈕;修正閱讀器顯示進度列時雙頁分欄失敗。
  • 0.4.0:改用本機 OCR(Tesseract)加 Haiku 翻譯文字;修正閱讀器重繪時譯文短暫閃回原文。

檔案

詳細設計見 docs/design.md。

  • manifest.json:Manifest V3 設定
  • page-hook.js:在 Kindle 頁面自己的環境裡包住 fetch,把閱讀器拿的頁面資料複製給 content script
  • page-render.js:解開頁面資料、照它畫出頁面、逐像素比對、找出段落和欄
  • content.js:在 Kindle 頁面保留頁面資料、辨識目前是哪一頁,並畫出譯文覆蓋層
  • background.js:決定翻哪一頁、呼叫 Claude API(結構化輸出)、段落快取、預讀下一頁、看圖模式的截圖
  • ocr-layout.js:把 OCR 讀到的行和字放進段落,標出每個字的樣式
  • styled-text.js:處理帶斜體、粗體、螢光標記的譯文
  • context-pages.js:挑選校對時參考的前面段落、整理人名對照表
  • offscreen.html/js:在 offscreen 文件裡執行 Tesseract(service worker 不能開 Web Worker)
  • sidepanel.html/js:側邊欄介面
  • options.html/js:設定頁(API key、翻譯方式、預先翻譯下一頁、參考前面的頁、effort、目標語言)
  • vendor/tesseract/:Tesseract.js 7.0.0、tesseract.js-core 和英文模型(Apache-2.0),全部打包在擴充功能裡,不從 CDN 載入
  • tests/:Node 測試(見下一節)

開發

測試用 Node 內建的 test runner,需要 Node 22 以上,沒有任何套件:

npm test                                                  # 全部
node --test tests/background-flow.test.js                 # 一個檔案
node --test --test-name-pattern="cache" "tests/**/*.test.js"  # 名稱符合的測試
node --test --watch "tests/**/*.test.js"                  # 改程式時自動重跑

測試把擴充功能的檔案原封不動地載入,周圍的 Chrome API、Kindle 頁面、OCR、Claude API 和 DOM 都換成假的,所以不需要瀏覽器、API key 或網路,跑一次約 20 秒。Kindle 的頁面資料用一本合成的書代替(Amazon 的字型不能放進 repo),canvas 是真的會填像素的假 canvas,所以辨識頁面的逐像素比對也測得到。Tesseract 的實際輸出和閱讀器真正的畫法不在測試範圍內,要在實際的 Kindle Cloud Reader 上確認。測試的架構見 docs/design.md 第 11 節。

GitHub Actions 在每次 push 和 PR 時用 Node 22、24 跑一次全部測試(.github/workflows/test.yml)。

改動擴充功能後,到 chrome://extensions 按擴充功能的重新載入,再重新整理 Kindle 分頁。

致謝

About

A Chrome extension that translates Kindle Cloud Reader books in place with Claude.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages