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にしています。

ページ番号2にあるフォーム・リージョンの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のアプリケーション作成の参考になれば幸いです。

完