Skip to content

Commit 95dda25

Browse files
alvinjioooAlvin Jireillyeon
authored
Introduce async TextDetector create and availability methods (#110)
This change introduces two new static methods to the TextDetector interface: * TextDetector.availability(options): Allows developers to quickly check if a given set of languages are supported for text detection. * TextDetector.create(options): A promise-based factory method that handles asynchronous resource setup and returns a TextDetector instance. Fixes #109. --------- Co-authored-by: Alvin Ji <alvinji@chromium.org> Co-authored-by: Reilly Grant <reillyeon@users.noreply.github.com>
1 parent 7499404 commit 95dda25

File tree

1 file changed

+104
-31
lines changed

1 file changed

+104
-31
lines changed

text.bs

Lines changed: 104 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ Please see the <a href="https://github.com/WICG/shape-detection-api/blob/gh-page
4242

4343
# Text Detection API # {#api}
4444

45-
Individual browsers MAY provide Detectors indicating the availability of hardware providing accelerated operation.
45+
Individual browsers MAY provide a {{TextDetector}} to perform text detection in images,
46+
potentially leveraging hardware acceleration or additional dependent libraries.
47+
The {{TextDetector/availability()}} method allows developers to check for the availability
48+
of these capabilities and specific language support.
4649

4750
## Image sources for detection ## {#image-sources-for-detection}
4851

@@ -52,16 +55,25 @@ Please refer to [[SHAPE-DETECTION-API#image-sources-for-detection]]
5255

5356
{{TextDetector}} represents an underlying accelerated platform's component for detection in images of Latin-1 text as defined in [[iso8859-1]]. It provides a single {{TextDetector/detect()}} operation on an {{ImageBitmapSource}} of which the result is a Promise. This method must reject this Promise in the cases detailed in [[#image-sources-for-detection]]; otherwise it may queue a task using the OS/Platform resources to resolve the Promise with a sequence of {{DetectedText}}s, each one essentially consisting on a {{DetectedText/rawValue}} and delimited by a {{DetectedText/boundingBox}} and a series of {{Point2D}}s.
5457

55-
<div class="example">
56-
Example implementations of Text code detection are e.g. <a href="https://developers.google.com/android/reference/com/google/android/gms/vision/text/package-summary">Google Play Services</a>, <a href="https://developer.apple.com/reference/coreimage/cidetectortypetext">Apple's CIDetector</a> (bounding box only, no OCR) or <a href="https://msdn.microsoft.com/en-us/library/windows/apps/windows.media.ocr.aspx">Windows 10 <abbr title="Optical Character Recognition">OCR</abbr> API</a>.
57-
</div>
58+
5859

5960
<xmp class="idl">
61+
dictionary TextDetectorOptions {
62+
required sequence<DOMString> languages;
63+
};
64+
65+
dictionary TextDetectorCreateOptions {
66+
AbortSignal signal;
67+
sequence<DOMString> languages;
68+
};
69+
6070
[
6171
Exposed=(Window,Worker),
6272
SecureContext
6373
] interface TextDetector {
6474
constructor();
75+
static Promise<Availability> availability(TextDetectorOptions options);
76+
static Promise<TextDetector> create(optional TextDetectorCreateOptions options = {});
6577
Promise<sequence<DetectedText>> detect(ImageBitmapSource image);
6678
};
6779
</xmp>
@@ -73,10 +85,51 @@ Example implementations of Text code detection are e.g. <a href="https://develop
7385
Detectors may potentially allocate and hold significant resources. Where possible, reuse the same {{TextDetector}} for several detections.
7486
</div>
7587
</dd>
88+
<dt><dfn method for="TextDetector"><code>availability(TextDetectorOptions |options|)</code></dfn></dt>
89+
<dd>
90+
<p>
91+
Returns a {{Promise}} that resolves with an {{Availability}} object
92+
indicating the overall availability status for the specified |options| languages for text
93+
detection.
94+
</p>
95+
<p>
96+
The returned {{Availability}} value is determined by the following precedence,
97+
applied across all requested languages:
98+
</p>
99+
<ul>
100+
<li>If any requested language is <code>"unavailable"</code>, the method returns
101+
<code>"unavailable"</code>.</li>
102+
<li>Otherwise, if any requested language is <code>"downloadable"</code>, the method
103+
returns <code>"downloadable"</code>.</li>
104+
<li>Otherwise, if any requested language is <code>"downloading"</code>, the method
105+
returns <code>"downloading"</code>.</li>
106+
<li>Otherwise, all requested languages are <code>"available"</code>, and the method
107+
returns <code>"available"</code>.</li>
108+
</ul>
109+
<div class="note">
110+
This method allows developers to check for specific language support before
111+
attempting to create a {{TextDetector}} instance.
112+
</div>
113+
</dd>
114+
<dt><dfn method for="TextDetector"><code>create(optional TextDetectorCreateOptions |options|)</code></dfn></dt>
115+
<dd>
116+
<p>
117+
Returns a {{Promise}} that resolves with a new {{TextDetector}}
118+
instance.
119+
</p>
120+
<div class="note">
121+
This factory method handles the asynchronous initialization of the
122+
text detector, including downloading necessary resources. It is recommended
123+
to use this asynchronous method over the synchronous constructor
124+
to accommodate potential delays from dependency downloads or initialization,
125+
ensuring a smoother user experience.
126+
</div>
127+
</dd>
76128
<dt><dfn method for="TextDetector"><code>detect(ImageBitmapSource |image|)</code></dfn></dt>
77129
<dd>Tries to detect text blocks in the {{ImageBitmapSource}} |image|.</dd>
78130
</dl>
79131

132+
80133
### {{DetectedText}} ### {#detectedtext-section}
81134

82135
<xmp class="idl">
@@ -102,49 +155,66 @@ dictionary DetectedText {
102155

103156
<i>This section is non-normative.</i>
104157

105-
<p class="note">
106-
Slightly modified/extended versions of these examples (and more) can be found in
107-
e.g. <a href="https://codepen.io/collection/DwWVJj/">this codepen collection</a>.
108-
</p>
109158

110-
## Platform support for a text detector ## {#example-feature-detection}
111159

112-
<div class="note">
113-
The following example can also be found in e.g. <a
114-
href="https://codepen.io/miguelao/pen/PbYpMv?editors=0010">this codepen</a>
115-
with minimal modifications.
116-
</div>
160+
## Platform support for a text detector ## {#example-feature-detection}
117161

118162
<div class="example">
119163
```js
120-
if (window.TextDetector == undefined) {
164+
if (!('TextDetector' in window)) {
121165
console.error('Text Detection not supported on this platform');
166+
} else {
167+
const languages = ['en', 'es']; // English and Spanish
168+
TextDetector.availability({ languages: languages }).then(availability => {
169+
if (availability === 'unavailable') {
170+
console.log('Not all of the requested languages are supported.');
171+
return;
172+
}
173+
174+
if (availability === 'downloadable') {
175+
console.log('Languages need to be downloaded first.');
176+
} else if (availability === 'downloading') {
177+
console.log('Languages are currently being downloaded.');
178+
} else {
179+
console.log('All requested languages are supported.');
180+
}
181+
182+
// Now you can create a TextDetector with the supported languages.
183+
// If the status was 'downloadable' or 'downloading', create() will wait
184+
// for the download to finish before resolving.
185+
TextDetector.create({ languages: languages }).then(detector => {
186+
// ... use the detector
187+
});
188+
});
122189
}
123190
```
124191
</div>
125192

126193
## Text Detection ## {#example-text-detection}
127194

128-
<div class="note">
129-
The following example can also be found in e.g.
130-
<a href="https://codepen.io/miguelao/pen/ygxVqg">this codepen</a>.
131-
</div>
195+
132196

133197
<div class="example">
134198
```js
135-
let textDetector = new TextDetector();
136-
// Assuming |theImage| is e.g. a &lt;img> content, or a Blob.
137-
138-
textDetector.detect(theImage)
139-
.then(detectedTextBlocks => {
140-
for (const textBlock of detectedTextBlocks) {
141-
console.log(
142-
'text @ (${textBlock.boundingBox.x}, ${textBlock.boundingBox.y}), ' +
143-
'size ${textBlock.boundingBox.width}x${textBlock.boundingBox.height}');
199+
(async () => {
200+
// Assuming |theImage| is e.g. a <img> content, or a Blob.
201+
try {
202+
// The legacy synchronous constructor is still supported,
203+
// but the async create() method is recommended.
204+
// let textDetector = new TextDetector();
205+
206+
let textDetector = await TextDetector.create();
207+
208+
const detectedTextBlocks = await textDetector.detect(theImage);
209+
for (const textBlock of detectedTextBlocks) {
210+
console.log(
211+
`text @ (${textBlock.boundingBox.x}, ${textBlock.boundingBox.y}), ` +
212+
`size ${textBlock.boundingBox.width}x${textBlock.boundingBox.height}`);
213+
}
214+
} catch (e) {
215+
console.error("Text Detection failed, boo.", e);
144216
}
145-
}).catch(() => {
146-
console.error("Text Detection failed, boo.");
147-
})
217+
})();
148218
```
149219
</div>
150220

@@ -154,6 +224,9 @@ spec: html
154224
text: allowed to show a popup
155225
text: in parallel
156226
text: incumbent settings object
227+
spec: writing-assistance-apis
228+
type: enum
229+
text: Availability
157230
</pre>
158231

159232
<pre class="biblio">

0 commit comments

Comments
 (0)