2022年12月13日火曜日

画像ビューワーのアプリを改良する

以前の記事で作成した、画像をオブジェクト・ストレージにアップロードするアプリを少々手直ししてみました。

元記事は以下になります。

APEXアプリに埋め込む画像をオブジェクト・ストレージに配置する
http://apexugj.blogspot.com/2022/09/image-viewer-preauth-obs.html


ファイル選択の代わりにカメラを起動


タイプファイル参照...のページ・アイテムP2_IMAGE詳細カスタム属性として、以下を記述します。

capture="environment" accept="image/*"


これでスマホからファイル選択を行なった場合、背面カメラが起動します。

ファイル選択のダイアログが画面いっぱいで開くよう、ページ番号2の外観テンプレート・オプションを開きます。


Stretch to Fit Windowにチェックを入れます。




ファイルを送信する前にプレビューを表示


非表示のページ・アイテムP2_URLを作成します。これは、カメラで写真をとったときのプレビューには使用しません。


プレビューを表示するリージョンを作成します。

識別タイトルPreviewタイプ静的コンテンツを選択します。ソースHTMLコードとして以下を記述します。

<img id="preview" src="&P2_URL."></img>

外観テンプレートとして、装飾のないBlank with Attributesを選択します。


画像のプレビューを表示するので、ページ・アイテムP2_IMAGEのファイルの選択はシンプルな表示形式Native File Browseに変更します。


ページ・アイテムP2_IMAGEでファイルが選択されたときに、動的アクションを実行します。

タイミングイベント変更選択タイプアイテムアイテムP2_IMAGEのときに、アクション選択した画像のプレビューを実行します。


アクション選択した画面のプレビューアクションJavaScriptコードの実行設定コードとして以下を記述します。



プレビューとして表示する画像のサイズを画面の横幅に合わせます。ページ・プロパティCSSインラインに以下を記述します。
#preview {
    width: 100%;
}

以上で完了です。

PCからの実行なのでカメラは起動しませんが、選択した画像のプレビューが表示されます。




編集時に画像を表示



フォームのページのレンダリング前ヘッダーの前にプロセスを作成します。ページ・アイテムP2_URLにオブジェクト・ストレージに保存されている画像のURLを設定します。

識別名前画像URLの取得とします。タイプコードの実行を選択し、コードとして以下を記述します。
select :G_PREAUTH_URL || g.location into :P2_URL
from img_items i join 
(
    select id, item_id, location, file_name, mime_type from
        (
            select
                row_number() over (partition by item_id order by last_updated desc) rn,
                id, item_id, location, file_name, mime_type
            from img_images
        )
    where rn = 1
) g on i.id = g.item_id
where i.id = :P2_ID;
ファイルの更新または削除時に実行されるように限定するため、サーバー側の条件タイプアイテムはNULLではないを選択し、アイテムとしてP2_IDを指定します。

以上で対応完了です。以下のように動作します。




現在位置を保存



APEX 22.2から、動的アクション現在の位置の取得が追加されました。この機能を使って、画像を選択した場所を表IMG_ITEMSに保存します。

CURRENT_LOCATIONを追加します。

alter table img_items add (current_location varchar2(400));

GeoJSONで保存する予定ですが、サンプルなので列の型はVARCHAR2にしています。

ページ番号にあるフォーム・リージョンのImg Itemで、ページ・アイテムの同期化を実行します。フォームにページ・アイテムP2_CURRENT_LOCATONが追加されます。識別タイプ非表示に変更します。

動的アクションによって値を設定するため、設定保護された値OFFにします。


動的アクションの画像の選択にTRUEアクションを追加します。

識別アクションとして現在の位置の取得を選び、設定戻り値としてGeoJSONアイテムとしてP2_CURRENT_LOCATIONを選択します。


取得した位置をカードに表示するため、カード・リージョンのソースを変更します。
select i.id, i.name, :G_PREAUTH_URL || g.location location, g.file_name, i.current_location
from img_items i join 
(
    select id, item_id, location, file_name, mime_type from
        (
            select
                row_number() over (partition by item_id order by last_updated desc) rn,
                id, item_id, location, file_name, mime_type
            from img_images
        )
    where rn = 1
) g on i.id = g.item_id

列の同期化を行い、カード・リージョンの属性サブタイトルとしてCURRENT_LOCATIONを選択します。


以上でアプリケーションは完成です。

写真のExifからではありませんが、撮影場所の座標を取得することができます。


APEXの処理はOracle Databaseで行われるため、バイナリ・データの操作は得意ではありません。画像などは、オブジェクト・ストレージに配置した際にイベント・サービスなどを使って処理した方が良いと思います。

以上です。

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

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