2024年7月23日火曜日

MLEのJavaScriptでコードを記述したプロセスを作成しデータベースでJPEG画像のリサイズを行なう

Oracle Database 23aiではMLEとしてGraalVMが組み込まれ、サーバー側でJavaScriptのコードを実行できるようになっています。Oracle Database 23ai上で実行されているOracle APEXでは、今までPL/SQLを記述できたほとんどの箇所で、PL/SQLの代わりにJavaScriptを記述できるようになりました。

本記事では、MLE JavaScriptを使った例として、JPEG画像のリサイズを行なうアプリケーションを作成します。JPEG画像のデコード、エンコードおよびリサイズはMLEのJavaScriptで実行します。

作成したアプリケーションは以下のように動作します。


以下より作成手順を紹介します。

最初にJPEG画像を操作するMLEモジュールを作成します。

SQLワークショップオブジェクト・ブラウザを開きます。


MLEモジュール - JavaScriptをクリックし、MLEモジュールの作成を始めます。

最初にnpmのjpeg-jsを元にしたMLEモジュールを作成します。

名前ESM_JPEG_JS_0_4_4バージョン0.4.4ソース・タイプURLを選択し、URLとして以下を指定します。

https://cdn.jsdelivr.net/npm/jpeg-js@0.4.4/+esm

MLEモジュールの作成をクリックします。


MLEモジュールESM_JPEG_JS_0_4_4が作成されます。


MLEモジュールの作成を続けます。

最初にnpmのbufferを元にしたMLEモジュールを作成します。

名前ESM_BUFFER_6_0_3バージョン6.0.3ソース・タイプURLを選択し、URLとして以下を指定します。

https://cdn.jsdelivr.net/npm/buffer@6.0.3/+esm


モジュールbufferが参照しているモジュールbase64-jsieee754を、それぞれMLEモジュールとして作成します。

base64-jsのMLEモジュールを作成します。

名前ESM_BASE64_JS_1_5_1バージョン1.5.1ソース・タイプURLを選択し、URLとして以下を指定します。

https://cdn.jsdelivr.net/npm/base64-js@1.5.1/+esm


ieee754のMLEモジュールを作成します。

名前ESM_IEEE754_1_2_1バージョン1.2.1ソース・タイプURLを選択し、URLとして以下を指定します。

https://cdn.jsdelivr.net/npm/ieee754@1.2.1/+esm


画像のリサイズを行なうMLEモジュールを作成します。

名前RESIZEソース・タイプURLを選択し、URLとして以下を指定します。

https://cdn.jsdelivr.net/npm/@jimp/plugin-resize@0.22.12/es/modules/resize.js


以上で必要なMLEモジュールが作成できました。


作成したMLEモジュールをインポートとして含むMLE環境を作成します。


作成するMLE環境名前IMAGE_ENVとします。

MLE環境の作成をクリックします。


MLE環境IMAGE_ENVが作成されます。インポートの追加をクリックします。


モジュール所有者APEXワークスペース・スキーマを選択します。

モジュール名としてESM_JPEG_JS_0_4_4を選択します。インポート名/npm/jpeg-js@0.4.4/+esmとします。

作成をクリックします。


同様に、以下のモジュール名インポート名の組みを作成します。インポート名は、jsDelivr.comによって自動生成されたESモジュールに含まれるimport文の参照と一致する必要があります。モジュールresizeは自動生成されたコードではないため、インポート名はそのままresizeとしています。

モジュール名:ESM_BUFFER_6_0_3、インポート名:/npm/buffer@6.0.3/+esm
モジュール名:ESM_BASE64_JS_1_5_1、インポート名:/npm/base64-js@1.5.1/+esm
モジュール名:ESM_IEEE754_1_2_1、インポート名:/npm/ieee754@1.2.1/+esm
モジュール名:RESIZE、インポート名:resize

MLE環境IMAGE_ENVに5つのMLEモジュールがインポートとして登録されていれば、MLE環境の準備は完了です。


APEXのアプリケーションを作成します。

リサイズ前のオリジナルの画像とリサイズ後の画像を保存する表として、EBMJ_IMAGESを作成します。以下のDDLを実行します。
create table ebmj_images (
    id                 number generated by default on null as identity
                       constraint ebmj_images_id_pk primary key,
    title              varchar2(80 char) not null,
    image              blob,
    image_mimetype     varchar2(80 char),
    image2             blob,
    image2_mimetype    varchar2(80 char)
);

アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。名前Image Resizeとします。


元画像を登録するためのページを作成します。

EBMJ_IMAGESソースとしたフォーム付き対話モード・レポートのページを作成します。


ページ・タイプとして対話モード・レポートを選択します。

対話モード・レポートページ番号名前Imagesとします。フォーム・ページを含めるチェックを入れます。

フォーム・ページ番号フォーム・ページ名Imageフォーム・ページ・モードドロワーを選択します。

データ・ソース表/ビューの名前としてEBMJ_IMAGESを選択します。

へ進みます。


主キー列1としてID (Number)を選択します。

ページの作成を実行します。


対話モード・レポートとフォームのページが作成されます。

ページ・デザイナで対話モード・レポートのページを開き、画像を保存しているBLOB列の属性を調整します。

IMAGEを選択し、BLOB属性MIMEタイプ列としてIMAGE_MIMETYPEを設定します。


同様に列IMAGE2を選択し、BLOB属性MIMEタイプ列としてIMAGE2_MIMETYPEを設定します。


ページ・デザイナでフォームのページを開きます。

ページ・アイテムP3_IMAGEを選択し、ストレージMIMEタイプ列としてIMAGE_MIMETYPEを設定します。


列IMAGE_MIMETYPE、IMAGE2、IMAGE2_MIMETYPEに対応するページ・アイテムP3_IMAGE_MIMETYPEP3_IMAGE2P3_IMAGE2_MIMETYPEはサーバー側で設定し、画面からは設定しません。

これらのページ・アイテムを選択し、コメント・アウトします。


以上で元画像を登録するページは完成です。


アプリケーションを実行し、リサイズの元画像となるJPEG画像を登録します。

Imagesのページを開き、作成をクリックします。


ドロワーが開きます。Titleを入力し、ImageにJPEG画像を選択します。

作成をクリックします。


作成したJPEG画像が一覧されます。同様の手順を繰り返し、JPEG画像をいくつか登録します。


ページ・デザイナでホーム・ページを開きます。画像のリサイズを行なうUIを実装します。

リサイズの元画像を選択するページ・アイテムを作成します。

識別名前P1_IDタイプ選択リストラベルImageとします。設定選択時のページ・アクションとして値のリダイレクトと設定を選択します。

LOVタイプSQL問合せSQL問合せとして以下を記述します。

select title d, id r from ebmj_images

追加値の表オフNULL値の表示オンNULL表示値として- Select Image -を記述します。

セッション・ステートストレージセッションごと(永続)を選択します。


縮小する比率を指定するページ・アイテムを作成します。例えば10を指定すると、画像の横と縦がそれぞれ1/10となり、面積としては1/100になります。

識別名前P1_SCALEタイプ数値フィールドラベルScaleとします。外観テンプレートとしてRequired - Floartingを選択します。検証必須の値オンデフォルトタイプ静的とし、静的値10を設定します。セッション・ステートストレージとしてセッションごと(永続)を選択します。


リサイズを実行するボタンを作成します。

識別ボタン名RESIZEラベルResizeとします。外観ホットオンテンプレート・オプションWidthStretchを選択します。

動作アクションはデフォルトのページの送信です。


リサイズ前の画像を表示するページ・アイテムを作成します。

識別名前P1_IMAGEタイプイメージの表示ラベルOriginalとします。設定基準としてSQL文で戻されたBLOB列を選択し、SQL文として以下を記述します。

select image from ebmj_images where id = :P1_ID

セッション・ステートストレージリクエストごと(メモリーのみ)とします。


リサイズ後の画像を表示するページ・アイテムを作成します。

識別名前P1_IMAGE2タイプイメージの表示ラベルResizedとします。設定基準としてSQL文で戻されたBLOB列を選択し、SQL文として以下を記述します。

select image2 from ebmj_images where id = :P1_ID

元の画像の右隣に配置するため、レイアウト新規行の開始オフにします。

セッション・ステートストレージリクエストごと(メモリーのみ)とします。


JPEG画像のリサイズを行なうプロセスを作成します。

識別名前Resize JPEGタイプコードの実行です。

ソース言語JavaScript (MLE)を選択し、JavaScriptコードとして以下を記述します。

サーバー側の条件ボタン押下時RESIZEを指定します。


最後に、アプリケーション定義セキュリティを開き、データベース・セッションMLE環境としてIMAGE_ENVを設定します。

変更の適用をクリックすると、アプリケーションは完成です。


アプリケーションを実行すると、記事の先頭にあるGIF動画のように動作します。

GIF動画ではScaleの10を指定し、横と縦の幅がそれぞれ1/10となるように設定していますが、それほど小さくなっていないように見えます。これは、元の画像がブラウザの画面サイズに合わせて縮小されて表示されているためです。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/mle-image-resize.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。