chrome.documentScan

bởi

trong

Lưu ý quan trọng: API này chỉ hoạt động trên ChromeOS.

Mô tả

Document Scan API được thiết kế để cho phép các ứng dụng và tiện ích xem nội dung của tài liệu giấy trên một trình quét tài liệu đính kèm.

Quyền

Phạm vi cung cấp

Tình trạng có sẵn của các thành viên API được thêm sau sẽ xuất hiện cùng với các thành viên đó.

Khái niệm và cách sử dụng

API này hỗ trợ hai phương thức quét tài liệu. Nếu trường hợp sử dụng của bạn có thể hoạt động với bất kỳ máy quét nào và không yêu cầu kiểm soát cấu hình, hãy sử dụng phương thức scan(). Các trường hợp sử dụng phức tạp hơn đòi hỏi phải kết hợp các phương thức, chỉ được hỗ trợ trong Chrome 124 trở lên.

Quét đơn giản

Đối với các trường hợp sử dụng đơn giản, nghĩa là những trường hợp có thể hoạt động với mọi máy quét và không yêu cầu kiểm soát cấu hình, hãy gọi scan(). Phương thức này lấy một đối tượng ScanOptions và trả về một Lời hứa sẽ phân giải bằng một đối tượng ScanResults. Các chức năng của tuỳ chọn này chỉ giới hạn ở số lần quét và các loại MIME mà phương thức gọi sẽ chấp nhận. Các lượt quét được trả về dưới dạng URL để hiển thị trong thẻ <img> cho giao diện người dùng.

Quét phức tạp

Quá trình quét phức tạp được thực hiện theo 3 giai đoạn như mô tả trong phần này. Bảng tóm tắt này không mô tả mọi đối số phương thức hoặc mọi thuộc tính được trả về trong phản hồi. Bài viết này chỉ nhằm cung cấp cho bạn hướng dẫn chung về cách viết mã trình quét.

Lưu ý: Việc gọi openScanner(), getScannerList() hoặc startScan() nhiều lần sẽ huỷ các thao tác do các lệnh gọi trước đó đến các phương thức này khởi tạo. Hãy xem nội dung mô tả về các phương thức này để biết thông tin chi tiết.

Chiến dịch Khám phá

  1. Gọi getScannerList(). Các trình quét có sẵn sẽ được trả về trong một Lời hứa phân giải bằng GetScannerListResponse.

    • Đối tượng phản hồi chứa một mảng các đối tượng ScannerInfo.
    • Mảng này có thể chứa nhiều mục nhập cho một máy quét nếu máy quét đó hỗ trợ nhiều giao thức hoặc phương thức kết nối.
  2. Chọn một trình quét trong mảng được trả về và lưu giá trị của thuộc tính scannerId.

    Sử dụng các thuộc tính của từng đối tượng ScannerInfo để phân biệt giữa nhiều đối tượng cho cùng một trình quét. Các đối tượng từ cùng một trình quét sẽ có cùng giá trị cho thuộc tính deviceUuid. ScannerInfo cũng chứa một thuộc tính imageFormats chứa một mảng các loại hình ảnh được hỗ trợ.

Cấu hình máy quét

  1. Gọi openScanner(), truyền vào mã máy quét đã lưu. Phương thức này trả về một Lời hứa phân giải bằng OpenScannerResponse. Đối tượng phản hồi chứa:

    • Thuộc tính scannerHandle mà bạn cần lưu.

    • Một thuộc tính tuỳ chọn chứa các thuộc tính dành riêng cho máy quét mà bạn cần đặt. Hãy xem phần Truy xuất tuỳ chọn của trình quét để biết thêm thông tin.

  2. (Không bắt buộc) Nếu bạn cần người dùng cung cấp giá trị cho các tuỳ chọn của máy quét, hãy tạo một giao diện người dùng. Bạn sẽ cần các tuỳ chọn của trình quét do bước trước cung cấp và bạn sẽ cần truy xuất các nhóm tuỳ chọn do trình quét cung cấp. Hãy xem phần Tạo giao diện người dùng để biết thêm thông tin.

  3. Tạo một mảng các đối tượng OptionSetting bằng cách sử dụng các giá trị do lập trình hoặc do người dùng cung cấp. Hãy xem phần Đặt tuỳ chọn quét để biết thêm thông tin.

  4. Truyền mảng các đối tượng OptionSetting đến setOptions() để đặt các tuỳ chọn cho trình quét. Phương thức này trả về một Lời hứa giải quyết bằng SetOptionsResponse. Đối tượng này chứa phiên bản cập nhật của các tuỳ chọn máy quét được truy xuất ở bước 1 của cấu hình máy quét.

    Vì việc thay đổi một tuỳ chọn có thể làm thay đổi các điều kiện ràng buộc đối với một tuỳ chọn khác, nên bạn có thể cần lặp lại các bước này nhiều lần.

Đang quét

  1. Tạo một đối tượng StartScanOptions và truyền đối tượng đó vào startScan(). Phương thức này trả về một Lời hứa phân giải bằng StartScanResponse. Thuộc tính job của nó là một handle mà bạn sẽ sử dụng để đọc dữ liệu quét hoặc huỷ quá trình quét.

  2. Truyền handle công việc đến readScanData(). Phương thức này trả về một Lời hứa phân giải bằng đối tượng ReadScanDataResponse. Nếu dữ liệu được đọc thành công, thuộc tính result của dữ liệu đó sẽ bằng SUCCESS và thuộc tính data của dữ liệu đó sẽ chứa một ArrayBuffer với một phần của quá trình quét. Xin lưu ý rằng estimatedCompletion chứa tỷ lệ phần trăm ước tính của tổng dữ liệu đã được phân phối cho đến thời điểm hiện tại.

    Lưu ý: Nếu result là SUCCESS nhưng data trống, hãy trì hoãn một chút trước khi gọi lại readScanData().

  3. Lặp lại bước trước đó cho đến khi thuộc tính result bằng EOF hoặc gặp lỗi.

Khi quá trình quét kết thúc, hãy gọi closeScanner() bằng tay điều khiển máy quét đã lưu ở bước 3. Phương thức này trả về một Lời hứa phân giải bằng CloseScannerResponse. Việc gọi cancelScan() bất cứ lúc nào sau khi tạo công việc sẽ kết thúc quá trình quét.

Đối tượng phản hồi

Tất cả phương thức đều trả về một Lời hứa giải quyết bằng một đối tượng phản hồi thuộc một loại nào đó. Hầu hết các thuộc tính này đều chứa một thuộc tính result có giá trị là một thành viên của OperationResult. Một số thuộc tính của đối tượng phản hồi sẽ không chứa giá trị trừ phi giá trị của result có một giá trị cụ thể. Các mối quan hệ này được mô tả trong tài liệu tham khảo cho từng đối tượng phản hồi.

Ví dụ: OpenScannerResponse.scannerHandle sẽ chỉ có giá trị khi OpenScannerResponse.result bằng SUCCESS.

Tuỳ chọn máy quét

Các tuỳ chọn của máy quét có thể khác nhau đáng kể tuỳ theo thiết bị. Do đó, bạn không thể phản ánh các tuỳ chọn của máy quét ngay trong API documentScan. Để giải quyết vấn đề này, OpenScannerResponse (truy xuất bằng openScanner()) và SetOptionsResponse (đối tượng phản hồi cho setOptions()) chứa thuộc tính options. Đây là một đối tượng chứa các tuỳ chọn dành riêng cho máy quét. Mỗi tuỳ chọn là một ánh xạ khoá-giá trị, trong đó khoá là một tuỳ chọn dành riêng cho thiết bị và giá trị là một thực thể của ScannerOption.

Cấu trúc thường có dạng như sau:

{ “key1”: { scannerOptionInstance } “key2”: { scannerOptionInstance } }

Ví dụ: hãy tưởng tượng một trình quét trả về các tuỳ chọn có tên là “nguồn” và “độ phân giải”. Cấu trúc của đối tượng options được trả về sẽ có dạng như ví dụ sau. Để đơn giản, chỉ một phần câu trả lời ScannerOption được hiển thị.

{ “source”: { “name”: “source”, “type”: OptionType.STRING, … }, “resolution”: { “name”: “resolution”, “type”: OptionType.INT, … }, … }

Xây dựng giao diện người dùng

Mặc dù không bắt buộc phải sử dụng API này, nhưng bạn có thể muốn người dùng chọn giá trị cho một tuỳ chọn cụ thể. Điều này đòi hỏi phải có giao diện người dùng. Sử dụng OpenScannerResponse (do openScanner() mở) để truy xuất các tuỳ chọn cho máy quét đính kèm như mô tả trong phần trước.

Một số trình quét nhóm các tuỳ chọn theo cách dành riêng cho thiết bị. Các nhóm này không ảnh hưởng đến hành vi của tuỳ chọn, nhưng vì các nhóm này có thể được đề cập trong tài liệu sản phẩm của trình quét, nên người dùng sẽ thấy các nhóm đó. Bạn có thể truy xuất các nhóm này bằng cách gọi getOptionGroups(). Thao tác này sẽ trả về một Lời hứa phân giải bằng đối tượng GetOptionGroupsResponse. Thuộc tính groups chứa một mảng các nhóm dành riêng cho máy quét. Sử dụng thông tin trong các nhóm này để sắp xếp các tuỳ chọn trong OpenScannerResponse để hiển thị.

{ scannerHandle: “123456”, result: SUCCESS, groups: [ { title: “Standard”, members: [ “resolution”, “mode”, “source” ] } ] }

Như đã nêu trong phần Cấu hình trình quét, việc thay đổi một tuỳ chọn có thể làm thay đổi các quy tắc ràng buộc đối với một tuỳ chọn khác. Đó là lý do tại sao setOptionsResponse (đối tượng phản hồi cho setOptions()) chứa một thuộc tính options khác. Sử dụng phương thức này để cập nhật giao diện người dùng. Sau đó, hãy lặp lại nếu cần cho đến khi bạn thiết lập xong tất cả các tuỳ chọn.

Đặt tuỳ chọn máy quét

Đặt các tuỳ chọn của trình quét bằng cách truyền một mảng các đối tượng OptionSetting đến setOptions(). Ví dụ: hãy xem phần Quét một trang có kích thước thư sau đây.

Ví dụ

Truy xuất một trang dưới dạng blob

Ví dụ này cho thấy một cách truy xuất một trang từ máy quét dưới dạng blob và minh hoạ cách sử dụng startScan() và readScanData() bằng giá trị của OperationResult.

async function pageAsBlob(handle) { let response = await chrome.documentScan.startScan( handle, {format: “image/jpeg”}); if (response.result != chrome.documentScan.OperationResult.SUCCESS) { return null; } const job = response.job; let imgParts = []; response = await chrome.documentScan.readScanData(job); while (response.result == chrome.documentScan.OperationResult.SUCCESS) { if (response.data && response.data.byteLength > 0) { imgParts.push(response.data); } else { // Delay so hardware can make progress. await new Promise(r => setTimeout(r, 100)); } response = await chrome.documentScan.readScanData(job); } if (response.result != chrome.documentScan.OperationResult.EOF) { return null; } if (response.data && response.data.byteLength > 0) { imgParts.push(response.data); } return new Blob(imgParts, { type: “image/jpeg” }); }

Quét một trang có kích thước tiêu chuẩn

Ví dụ này cho thấy cách chọn một trình quét, thiết lập các tuỳ chọn của trình quét đó và mở trình quét. Sau đó, ứng dụng này truy xuất nội dung của một trang và đóng máy quét. Quy trình này minh hoạ cách sử dụng getScannerList(), openScanner(), setOptions() và closeScanner(). Lưu ý rằng nội dung của trang được truy xuất bằng cách gọi hàm pageAsBlob() trong ví dụ trước.

async function scan() { let response = await chrome.documentScan.getScannerList({ secure: true }); let scanner = await chrome.documentScan.openScanner( response.scanners[0].scannerId); const handle = scanner.scannerHandle; let options = []; for (source of scanner.options[“source”].constraint.list) { if (source.includes(“ADF”)) { options.push({ name: “source”, type: chrome.documentScan.OptionType.STRING, value: { value: source } }); break; } } options.push({ name: “tl-x”, type: chrome.documentScan.OptionType.FIXED, value: 0.0 }); options.push({ name: “br-x”, type: chrome.documentScan.OptionType.FIXED, value: 215.9 // 8.5″ in mm }); options.push({ name: “tl-y”, type: chrome.documentScan.OptionType.FIXED, value: 0.0 }); options.push({ name: “br-y”, type: chrome.documentScan.OptionType.FIXED, value: 279.4 // 11″ in mm }); response = await chrome.documentScan.setOptions(handle, options); let imgBlob = await pageAsBlob(handle); if (imgBlob != null) { // Insert imgBlob into DOM, save to disk, etc } await chrome.documentScan.closeScanner(handle); }

Hiển thị cấu hình

Như đã nêu ở nơi khác, để hiển thị các tuỳ chọn cấu hình của máy quét cho người dùng, bạn cần gọi getOptionGroups() ngoài các tuỳ chọn máy quét được trả về từ lệnh gọi đến openScanner(). Điều này giúp hiển thị các tuỳ chọn cho người dùng trong các nhóm do nhà sản xuất xác định. Ví dụ này cho thấy cách thực hiện việc đó.

async function showConfig() { let response = await chrome.documentScan.getScannerList({ secure: true }); let scanner = await chrome.documentScan.openScanner( response.scanners[0].scannerId); let groups = await chrome.documentScan.getOptionGroups(scanner.scannerHandle); for (const group of groups.groups) { console.log(“=== ” + group.title + ” ===”); for (const member of group.members) { const option = scanner.options[member]; if (option.isActive) { console.log(” ” + option.name + ” = ” + option.value); } else { console.log(” ” + option.name + ” is inactive”); } } } }