Documentation
¶
Overview ¶
Package chromeocr calls Google Chrome's on-device "Screen AI" OCR component directly — the same local ML model Chrome uses to make scanned PDFs and images searchable — without needing a running browser.
Index ¶
- Variables
- func AreOnSameLine(boxA, boxB BoundingBox) bool
- func CleanLeadingNoisePunct(s string) string
- func CorrectLegalTriggers(s string) string
- func CorrectWithIndonesianDict(s string) string
- func DownloadComponent(targetDir string) (string, error)
- func FixMergedLegalWords(s string) string
- func GetOriginalStderr() io.Writer
- func GetOriginalStdout() io.Writer
- func InjectTextLayer(inputPath, outputPath string, pages []overlayPage) error
- func IsCanonicalLegalTrigger(w string) bool
- func IsDiagonalWatermark(ln Line) bool
- func IsKnownIndonesianWord(w string) bool
- func IsLegalMarginLabel(s string) bool
- func IsPageNumberOrHeaderFooter(ln Line, imgHeight int32) bool
- func LoadCustomDictionaryFile(filePath string) error
- func NormalizeIndonesian(s string) string
- func ReadPDFPageSizes(pdfPath string) ([][2]float64, error)
- func SilenceNativeOutputs()
- func StripTextOperators(streamBody []byte) []byte
- type Block
- type BoundingBox
- type ContentType
- type Direction
- type Engine
- func (e *Engine) Close() error
- func (e *Engine) MaxImageDimension() int
- func (e *Engine) OCRFile(path string) (Page, error)
- func (e *Engine) OCRImage(img image.Image) (Page, error)
- func (e *Engine) OCRImageAutoOrient(img image.Image) (Page, error)
- func (e *Engine) OCRImageTiled(img image.Image) (Page, error)
- func (e *Engine) OCRPDF(pdfPath string, firstPage, lastPage int) ([]Page, error)
- func (e *Engine) OCRToSearchablePDF(inputPDF, outputPDF string) ([]Page, error)
- func (e *Engine) ProcessImages(images []image.Image) (*PDFResult, error)
- func (e *Engine) ProcessPDF(inputPDF, outputPDF string) (*PDFResult, error)
- func (e *Engine) ProcessPDFSmart(inputPDF, outputPDF string) (*PDFResult, error)
- func (e *Engine) Version() (major, minor uint32)
- type LibraryNotFoundError
- type Line
- type LineDetail
- type LowConfWord
- type Option
- type PDFResult
- type Page
- type PageJSON
- type PageProgress
- type PageSkewInfo
- type SubImageable
- type Word
- type WordDetail
Constants ¶
This section is empty.
Variables ¶
var LegalKeywords = []string{
"MENIMBANG", "MENGINGAT", "MEMPERHATIKAN", "MEMUTUSKAN", "MENETAPKAN",
"KESATU", "KEDUA", "KETIGA", "KEEMPAT", "KELIMA", "KEENAM", "KETUJUH", "KEDELAPAN", "KESEMBILAN", "KESEPULUH",
"PASAL", "BAB", "LAMPIRAN", "SALINAN", "KEPADA", "UNTUK", "TENTANG", "NOMOR",
"UNDANG-UNDANG", "PERATURAN", "KEPUTUSAN", "INSTRUKSI", "QANUN", "EDARAN", "SURAT",
"PRESIDEN", "PEMERINTAH", "MENTERI", "GUBERNUR", "BUPATI", "WALIKOTA", "WALIKOTA",
"PROPINSI", "PROVINSI", "KABUPATEN", "KOTA", "DAERAH", "GAMPONG", "DESA",
}
LegalKeywords contains standard Indonesian legal document structural markers (National to Regency/City levels).
var WatermarkKeywords = []string{
"DRAFT", "WATERMARK", "COPY", "CONFIDENTIAL", "RAHASIA", "SAMPLE", "CONTOH", "ARSIP",
}
WatermarkKeywords contains common watermark terms found in legal & official documents.
Functions ¶
func AreOnSameLine ¶
func AreOnSameLine(boxA, boxB BoundingBox) bool
AreOnSameLine checks if two bounding boxes are on the same printed line height (vertical overlap >= 30%).
func CleanLeadingNoisePunct ¶
CleanLeadingNoisePunct removes leading dots/commas before capital letters (e.g. ".Penetapan" -> "Penetapan").
func CorrectLegalTriggers ¶
func CorrectWithIndonesianDict ¶
CorrectWithIndonesianDict scores OCR candidate words against the Indonesian dictionary and safely corrects OCR digit/symbol corruptions (e.g. "Pasa1" -> "Pasal", "Nom0r" -> "Nomor"). Pure alphabetic words (like proper names "Safrizal", "Madjid", "Lhoksukon") are 100% PRESERVED and NEVER modified.
func DownloadComponent ¶
DownloadComponent attempts to download the screen_ai component directly from Google's update servers, without needing Chrome installed or running. It returns the directory the component was extracted into (pass this to WithModelDir).
This may fail with a "noupdate" error — see the package-level comment in download.go for why, and what to do instead.
func FixMergedLegalWords ¶
FixMergedLegalWords dynamically splits merged OCR words (e.g. "SumberDaya" -> "Sumber Daya", "PeraturanGubernur" -> "Peraturan Gubernur", "PERATURANGUBERNUR" -> "PERATURAN GUBERNUR", "SUMBERDAYA" -> "SUMBER DAYA") without requiring any manual hardcoded maps.
func GetOriginalStderr ¶
GetOriginalStderr returns the saved terminal stderr writer.
func GetOriginalStdout ¶
GetOriginalStdout returns the saved terminal stdout writer for clean CLI progress logging.
func InjectTextLayer ¶
InjectTextLayer reads inputPath, strips any pre-existing text layer, injects a new invisible OCR text layer for every page, and writes the result to outputPath using a PDF incremental update so the original xref is never touched.
func IsCanonicalLegalTrigger ¶
IsCanonicalLegalTrigger checks if a word is part of the canonical Indonesian legal document structure (e.g. Menimbang, Mengingat, Memperhatikan, Memutuskan, Menetapkan, KESATU, KEDUA, KETIGA, Pasal, BAB, Lampiran, Nomor, Tentang).
func IsDiagonalWatermark ¶
IsDiagonalWatermark checks if a line represents a background watermark.
func IsKnownIndonesianWord ¶
IsKnownIndonesianWord checks if a word exists in our Indonesian dictionary.
func IsLegalMarginLabel ¶
IsLegalMarginLabel checks if a text line represents a legal margin/header label.
func IsPageNumberOrHeaderFooter ¶
IsPageNumberOrHeaderFooter checks if a line is a running header, footer, or page number marker.
func LoadCustomDictionaryFile ¶
LoadCustomDictionaryFile loads a plain text dictionary file (.txt or .dic) containing custom Indonesian words (one word per line), dynamically expanding the Language Model Dictionary Scorer at runtime.
func NormalizeIndonesian ¶
func ReadPDFPageSizes ¶
ReadPDFPageSizes reads MediaBox dimensions for every page in the PDF.
func SilenceNativeOutputs ¶
func SilenceNativeOutputs()
SilenceNativeOutputs redirects OS File Descriptor 1 (stdout) and 2 (stderr) to /dev/null so that native C++ glog / TensorFlow Lite logs are completely hidden, while preserving originalStdout for clean CLI progress logging.
func StripTextOperators ¶
StripTextOperators removes all "BT ... ET" text drawing blocks from a PDF content stream body, preserving all image/vector operators untouched.
Types ¶
type BoundingBox ¶
BoundingBox is a pixel-space rectangle returned by Screen AI. X, Y are the top-left corner in image space (origin top-left, Y downward). Angle is in radians, representing the clockwise rotation of the text element relative to the horizontal — the same field Chrome reads in pdf_accessibility_tree.cc to apply skew corrections.
func DeskewBox ¶
func DeskewBox(box BoundingBox, skew PageSkewInfo, imgW, imgH int) BoundingBox
type ContentType ¶
type ContentType int32
ContentType classifies what kind of content a line represents.
const ( ContentPrintedText ContentType = 0 ContentHandwrittenText ContentType = 1 ContentImage ContentType = 2 ContentLineDrawing ContentType = 3 ContentSeparator ContentType = 4 ContentUnreadableText ContentType = 5 ContentFormula ContentType = 6 ContentHandwrittenFormula ContentType = 7 ContentSignature ContentType = 8 )
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine is a loaded, initialized Screen AI OCR session.
func (*Engine) MaxImageDimension ¶
func (*Engine) OCRImageAutoOrient ¶
OCRImageAutoOrient replicates Chrome PDF Searchify behavior by testing page orientations (0°, 90° CW, 270° CW) and picking the rotation that maximizes recognized words for rotated/landscape pages.
func (*Engine) OCRImageTiled ¶
OCRImageTiled performs Tiled Segmented OCR for large high-resolution images (e.g. 300 DPI A4 scans). When an image's height exceeds maxDim, it splits the image into vertical tiles (height <= maxDim) and processes each tile at 100% 1:1 native 300 DPI resolution with ZERO downscaling blur!
func (*Engine) OCRPDF ¶
OCRPDF renders a PDF's pages to images and OCRs each one — the same two-step process Chrome itself performs internally (its built-in PDF renderer, pdfium, rasterizes a page; only then does that bitmap go to PerformOCR). chrome_screen_ai has no concept of "PDF" at all — see OCRImage's doc comment.
This shells out to `pdftoppm` (part of poppler-utils, NOT a Go module dependency — install it with e.g. `apt install poppler-utils` / `dnf install poppler-utils`) rather than pulling in a cgo PDF renderer, to keep this package's go.mod dependency-free. If your project already renders PDF pages another way (pdfium, MuPDF, ghostscript, ...), prefer calling OCRImage directly on those pages instead — that path has one less moving part.
firstPage and lastPage are 1-based and inclusive; pass 0, 0 to OCR every page. Pages are returned in order.
func (*Engine) OCRToSearchablePDF ¶
OCRToSearchablePDF OCRs every page of inputPDF, injects an invisible text layer, and writes the layered PDF to outputPDF.
func (*Engine) ProcessImages ¶
ProcessImages processes a slice of in-memory image.Image (e.g. rendered via go-fitz, image/png, etc.) using the active Engine session without re-initializing or closing Screen AI.
func (*Engine) ProcessPDF ¶
ProcessPDF processes inputPDF, generates outputPDF (layered PDF text layer) if outputPDF is non-empty, and returns a PDFResult containing clean full text (.txt) and page-by-page JSON array (.json).
func (*Engine) ProcessPDFSmart ¶
ProcessPDFSmart automatically detects if inputPDF already has a valid text layer. If valid text exists (>= 15 words per page), it restructures the text layer in 2D reading order in milliseconds. If the PDF is a scanned image (0 text layer), it automatically falls back to Screen AI OCR.
type LibraryNotFoundError ¶
type LibraryNotFoundError struct {
Searched []string
}
LibraryNotFoundError is returned when the screen_ai component could not be located automatically. It reports where chromeocr looked so the caller can decide whether to install Chrome, visit chrome://components to trigger a download, or pass an explicit path via WithModelDir / WithLibraryPath.
func (*LibraryNotFoundError) Error ¶
func (e *LibraryNotFoundError) Error() string
type Line ¶
type Line struct {
Text string
Language string
BlockID int32
ParagraphID int32
Confidence float32
Direction Direction
ContentType ContentType
Box BoundingBox
Words []Word
}
Line is a single recognized line of text.
func FilterLegalNoise ¶
FilterLegalNoise removes images, watermarks, page numbers, and running footers, and safely merges legal margin labels (Kepada, Untuk, KESATU, KEDUA, KETIGA, etc.) with colon bodies.
func OrganizeLegalLayoutLines ¶
OrganizeLegalLayoutLines sorts lines on a page into strict Indonesian legal reading order.
func SafeMergeLegalLabelLines ¶
SafeMergeLegalLabelLines merges a standalone legal label (Kepada, Untuk, KESATU, KEDUA, KETIGA, etc.) with its colon body text on the same line.
type LineDetail ¶
type LineDetail struct {
Text string `json:"text"`
Confidence float32 `json:"confidence"`
Box BoundingBox `json:"box"`
Words []WordDetail `json:"words,omitempty"`
}
LineDetail represents a single line's clean text, line confidence score, bounding box, and per-word details.
type LowConfWord ¶
type LowConfWord struct {
Page int `json:"page"`
Line string `json:"line"`
Word string `json:"word"`
Confidence float32 `json:"confidence"`
}
LowConfWord represents a single word with confidence below threshold, for human review.
type Option ¶
type Option func(*engineConfig)
Option configures New.
func WithAutoDownload ¶
func WithLibraryPath ¶
func WithLightMode ¶
func WithModelDir ¶
func WithProgress ¶
func WithProgress(fn func(PageProgress)) Option
func WithVerboseLogging ¶
type PDFResult ¶
type PDFResult struct {
Pages []Page `json:"pages"`
FullText string `json:"full_text"`
JSONPages []PageJSON `json:"json_pages"`
LowConfWords []LowConfWord `json:"-"`
}
PDFResult contains the full structured output from processing a PDF file.
func BuildPDFResult ¶
ProcessPDF processes inputPDF, generates outputPDF (layered PDF text layer) if outputPDF is non-empty, and returns a PDFResult containing clean full text (.txt) and page-by-page JSON array (.json). BuildPDFResult formats raw OCR pages into a clean PDFResult (.txt & .json page array).
func RestructurePDFTextLayer ¶
RestructurePDFTextLayer extracts an existing PDF text layer, re-orders all text in 2D reading order, cleans Indonesian legal preambles/watermarks, and injects the restructured text layer into outputPDF. Takes milliseconds and incurs ZERO OCR errors.
func (*PDFResult) BuildConfidenceReport ¶
BuildConfidenceReport returns a human-readable plain-text report of all words with confidence score below 0.85, grouped by page, for manual review.
func (*PDFResult) SaveOutputs ¶
SaveOutputs saves TXT, JSON, and optionally confidence report output files to disk.
type Page ¶
Page is the OCR result for a single image or PDF page. Width and Height are the pixel dimensions of the image fed to Screen AI (after any downscaling to respect MaxImageDimension). These dimensions are used by OCRToSearchablePDF to compute the exact scale factor: scaleX = page_width_pts / Width (Chrome's formula).
func ApplyDeskewToPage ¶
func ApplyDeskewToPage(page Page, skew PageSkewInfo) Page
func ExtractPDFTextLayerBBox ¶
ExtractPDFTextLayerBBox extracts all words and 2D bounding boxes from an existing PDF text layer.
type PageJSON ¶
type PageJSON struct {
Page int `json:"page"`
Text string `json:"text"`
Lines []LineDetail `json:"lines,omitempty"`
}
PageJSON represents a single page's clean extracted text and line details.
type PageProgress ¶
type PageProgress struct {
PageNum int
TotalPages int
Width int
Height int
IsTiled bool
TileCount int
Mode string
TotalWords int
LowConfCount int
Duration time.Duration
}
PageProgress provides processing metrics for a single page.
type PageSkewInfo ¶
func DetectPageSkew ¶
func DetectPageSkew(lines []Line) PageSkewInfo
type Word ¶
type Word struct {
Text string
Language string
Confidence float32
Box BoundingBox
}
Word is a single recognized word within a Line.
type WordDetail ¶
type WordDetail struct {
Text string `json:"text"`
Confidence float32 `json:"confidence"`
Box BoundingBox `json:"box"`
}
WordDetail represents a single word's clean text, word-level confidence score, and bounding box.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
chromeocr
command
|
|
|
chromeocr-download
command
Command chromeocr-download tries to fetch the screen_ai component directly from Google's update servers, without needing Chrome installed.
|
Command chromeocr-download tries to fetch the screen_ai component directly from Google's update servers, without needing Chrome installed. |
|
example
|
|
|
01-pdf-multi-output
command
|
|
|
02-single-image-ocr
command
|
|
|
03-in-memory-image-loop
command
|
|
|
04-custom-configuration
command
|
|
|
05-legal-document-cleaning
command
|