Recursive AI

Save and load the page as JSON

All oneocr recipes

Write a page to oneocr.page JSON, the documented and versioned format, and read it back under limits.

C#
using OneImage;
using OneOcr;
 
OcrEngine engine = OcrEngine.LoadBundled();
OcrPage page = Image.Load("receipt.png").Ocr(engine, new OcrOptions { Dpi = 192 });
 
var options = new OcrPageJsonOptions { Indented = true, IncludeChars = false };
string json = OcrPageJson.ToJson([page], options);
File.WriteAllText("receipt.page.json", json);
 
IReadOnlyList<OcrPage> again = OcrPageJson.Parse(File.ReadAllText("receipt.page.json"));
Console.WriteLine($"{json.Length} characters; read back: {again.Count} page, {again[0].Words.Count} words");
Console.WriteLine($"equal records: {again[0].Words.SequenceEqual(page.Words)}; same JSON: {OcrPageJson.ToJson(again, options) == json}");
 
string[] lines = json.Split('\n');
Console.WriteLine(string.Join('\n', lines.Take(9)));
int w = Array.FindIndex(lines, l => l.Contains("\"words\""));
Console.WriteLine(string.Join('\n', lines.Skip(w).Take(12)));
Text
27949 characters; read back: 1 page, 40 words
equal records: False; same JSON: True
{
  "format": "oneocr.page",
  "version": 1,
  "pageCount": 1,
  "pages": [
    {
      "index": 0,
      "width": 920,
      "height": 940,
              "words": [
                {
                  "text": "Corner",
                  "bounds": [314,69,445,100
                  ],
                  "visible": true,
                  "source": "ocr",
                  "confidence": 0.9839,
                  "rawConfidence": 0.9999
                },
                {
                  "text": "Market",
  • The JSON is deterministic: the same pages give the same bytes, and writing a page read back from JSON gives the same JSON again.
  • It is not a lossless copy of the objects in memory. Coordinates are rounded to three decimals and confidences to four, which is why the records read back don’t compare equal to the originals. Store the JSON, not the in-memory page, when you need to compare later.
  • bounds are [left, top, right, bottom] with y running down; every element has a source (ocr, textLayer or llm). The member names match OnePDF’s onepdf.extraction. The whole format is in oneocr.page JSON.
  • OcrPageJson.Parse checks sizes and depth against OcrLimits and throws OcrFormatException on bad input, so it is safe on files you didn’t write.
  • IncludeChars = false leaves out the per-character boxes, which make up most of the file.