ONNXモデルなのでONNX Runtime Webを使ってブラウザで実行することで、Oracle APEXのアプリでも利用できそうです。
ChatGPTにONNX Runtime WebとPaddleOCRを組み合わせた実装例を探してもらったところ、GitHub上の xulihang / paddleocr-browser を見つけてくれました。OnnxOCRは使用していませんが、ONNX Runtime Web、e-Search OCRとPaddleOCRを使って、ブラウザ上でOCRを実行しています。
色々見つけた結果を取捨選択して、ONNX Runtime Webとe-Search OCRとOnnxOCRを組み合わせて、ブラウザ上でOCRを実行するAPEXアプリケーションを作成してみました。
作成したAPEXアプリケーションは以下のように動作します。
e-Search OCRによる文字認識では文字を認識した位置も検出しますが、その表示は行なっていません。画像上に矩形を表示する手順については、以前に記事「HTMLの画像に重ねて矩形を描画する手順のまとめ」で紹介しています。
APEXアプリケーションですが、あまりAPEXの機能は使用していません。概ね静的サイトのホスティングに近い実装です。
以下にAPEXアプリケーションの作成手順について紹介します。
空のAPEXアプリケーションを作成します。名前はLocal OCRとします。作成したアプリケーションのホーム・ページに、すべての機能を実装します。
OCRにかける画像を選択するページ・アイテムと、OCRを実行するボタンを配置するリージョンとして、Controlsを作成します。タイプは静的コンテンツです。
外観のテンプレートにItem Containerを選択しています。テンプレート・オプションのAlighnmentにEndを選んでいます。今回はJavaScriptのコードを静的アプリケーション・ファイルにまとめ、APEXアクションとして呼び出します。APEXアクションのコンテキストをこのリージョンに作成するため、静的IDとしてCONTROLSを設定します。
OCRにかける画像を選択するページ・アイテムをP1_IMAGEとして作成します。タイプはイメージ・アップロードです。
レイアウトのリージョンはControls、スロットはItemです。
ページを送信してデータベース側で処理を行うことはないので、他の設定は処理に影響しません。
ページ・アイテムP1_IMAGEの値が変更されたときに、以下のJavaScriptコードが実行されるように動的アクションを作成します。
apex.actions.findContextById("CONTROLS").invoke("CHANGE");
ボタンであれば、カスタム属性data-actionで呼び出すAPEXアクションを指定できます。それ以外のコンポーネントでは、同等の属性はありません。そのため、動的アクションからAPEXアクションのCHANGEを呼び出します。APEXアクションCHANGEのコードは静的アプリケーション・ファイルに記述します。
OCRのスキャンを実行するボタンとしてSCANを作成します。
動作のアクションに動的アクションで定義を選択し、詳細のカスタム属性にdata-action="SCAN"を記述します。ボタンをクリックすると実行されるAPEXアクションSCANは、静的アプリケーション・ファイルに記述します。
選択した画像をプレビューするリージョンを作成します。タイプは静的コンテンツ、ソースのHTMLコードとして以下を記述します。
<img id="image" style="width:100%;"></img>
外観のテンプレート・オプションで、Body Heightを480pxに設定しています。
OCRで抽出した文字列を書き込むページ・アイテムとしてP1_TEXTを作成します。タイプはテキスト領域です。プレビューの右隣に配置するため、レイアウトの新規行の開始をオフにします。
以上でページのデザインは完成です。
ページ・プロパティのJavaScriptのファイルURLに以下を記述します。
https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js
[async]https://cdn.jsdelivr.net/npm/opencv.js/opencv.min.js
-- [module]#APP_FILES#app#MIN#.js
[module]#APP_FILES#ocr_reviewed_improved.js
最初にONNX Runtime Web(ort.min.js)をロードしています。次にOpenCVをロードしています。
続いて、OCRを実行するコードを記述した静的アプリケーション・ファイルをロードしています。私が書いたapp.jsはコメント・アウトしています。ocr_reviewed_improved.jsは、私が書いたapp.jsを、Claude Sonnet 4.5でレビューして書き直したコードです。
ページ・ロード時に実行に以下を記述し、ページ・ロード直後はボタンSCANを無効にします。OCRライブラリの初期化が完了した後に、ボタンSCANを有効にします。
document.getElementById("SCAN").disabled = true;
静的アプリケーション・ファイルとしてocr_reviewed_imporoved.jsを作成します。
ocr_reviewed_improved.jsのコードです。Claudeとのやり取りに興味がある方のために、チャットのリンクも掲載しておきます。
apex.message.showErrorsの使い方は間違っていましたが、そもそもapex.message.showErrorsをコードに追加したこと、使い方を教えるときちんとコードを修正したのには感心しました。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/local-ocr-with-onnxocr-and-paddleocr.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完