この章では、Oracle Multimediaのオブジェクト型を使用して、メディアをアップロードおよび取得するいくつかのタイプのWebアプリケーションについて説明します。この章では、次のOracle Multimediaフォト・アルバム・サンプルWebアプリケーションについて説明します。
3.1項では、Oracle Application ServerおよびOracle Database用のPL/SQL GatewayおよびPL/SQL Web Toolkitを使用する、PL/SQLフォト・アルバム・サンプル・アプリケーションについて説明します。
3.2項では、Oracle Multimedia Servlets and JSP Java APIを使用する、Java Servletフォト・アルバム・サンプル・アプリケーションについて説明します。
3.3項では、Oracle Multimedia Servlets and JSP Java APIを使用する、JSPフォト・アルバム・サンプル・アプリケーションについて説明します。
3.4項では、Microsoft Internet Information Server(IIS)Webサーバー用のActive Server Pages(ASP)/Visual Basic(VB)フォト・サンプル・アプリケーションについて説明します。
この章では、次のことを想定しています。
次の前提知識および経験がある。
PL/SQL GatewayおよびPL/SQL Web Toolkitを使用するPL/SQLアプリケーションの開発
JDBCを使用したJavaベースのWebアプリケーションの開発、Javaソース・コードの作成、Javaソース・コードのバイト・コード(.class)・ファイルへのコンパイル、およびOracle Application ServerとOracle Database用にOracle HTTP Serverで必要な、対応するサーブレット・コンテナへのクラス・ファイルのデプロイ
Microsoft IIS Webサーバー用のASP/VBスクリプトの作成
次のサンプル・アプリケーションをインストールおよび構成している。
Oracle Multimedia PL/SQL Web Toolkitフォト・アルバム・アプリケーション
Oracle Multimedia Javaサーブレット・フォト・アルバム・アプリケーション
Oracle Multimedia JSPフォト・アルバム・アプリケーション
Oracle Multimedia ASP/VBScriptフォト・アルバム・アプリケーション
インストールおよび構成の詳細は、各サンプル・アプリケーションのREADME.txtファイルを参照してください。
メディアをアップロードおよび取得するPL/SQL GatewayのWebアプリケーションである、Oracle Multimedia Code Wizardアプリケーションの詳細は、第4章を参照してください。
Oracle Multimedia IMExampleサンプル・アプリケーションの詳細は、第5章を参照してください。このサンプル・アプリケーションでは、Oracle Multimedia Java ClassesとOracle Multimediaオブジェクト型を使用して、Oracle Databaseのサンプル・スキーマからマルチメディア・データを取得、保存、再生および削除することができます。
Oracle Multimedia PL/SQL Web Toolkitフォト・アルバム・サンプル・アプリケーションは、次の操作の実行方法を示します。
Oracle Multimedia Imageオブジェクト型を使用して、Oracle Databaseに格納されているメディア・データをアップロード、取得および処理する。
Oracle Multimediaのイメージ・メタデータ・メソッドとOracle XML DBのXML文書管理機能、フルテキスト検索およびOracle Textの検索機能を組み合せ、バイナリ・イメージ・ファイルに埋め込まれているメタデータを抽出、格納および検索できるソリューションを作成する。
ユーザーから新規メタデータを収集し、そのメタデータをXML文書にフォーマットし、その文書をバイナリ・イメージで格納します。
インストール時に、フォト・アルバム・アプリケーションは、次の説明に重要な、多数のスキーマ・オブジェクトを作成します。これらのオブジェクトには、photos表が含まれます。この表は、次のCREATE TABLE文で定義されています。
CREATE TABLE photos( id NUMBER PRIMARY KEY,
description VARCHAR2(40) NOT NULL,
metaORDImage XMLTYPE,
metaEXIF XMLTYPE,
metaIPTC XMLTYPE,
metaXMP XMLTYPE,
image ORDSYS.ORDIMAGE,
thumb ORDSYS.ORDIMAGE )
--
-- store full-size images and thumbnail images as SecureFile LOBs
--
LOB(image.source.localdata) STORE AS SECUREFILE
LOB(thumb.source.localdata) STORE AS SECUREFILE;
--
-- and bind the XMLType columns to the interMedia metadata schemas
XMLType COLUMN metaORDImage
XMLSCHEMA "http://xmlns.oracle.com/ord/meta/ordimage"
ELEMENT "ordImageAttributes"
XMLType COLUMN metaEXIF
XMLSCHEMA "http://xmlns.oracle.com/ord/meta/exif"
ELEMENT "exifMetadata"
XMLType COLUMN metaIPTC
XMLSCHEMA "http://xmlns.oracle.com/ord/meta/iptc"
ELEMENT "iptcMetadata"
XMLType COLUMN metaXMP
XMLSCHEMA "http://xmlns.oracle.com/ord/meta/xmp"
ELEMENT "xmpMetadata";
image列およびthumb列のデータ型は、Oracle Multimedia Imageオブジェクト型として定義されています。これらの列は、それぞれ原寸イメージおよび生成された縮小イメージを格納するために使用されます。LOB記憶域句は、原寸イメージに対する記憶域が32KBのチャンクに割り当てられることを示します。これにより、イメージ・データの最速な読取りおよび書込みが可能になります。同様に、縮小イメージの記憶域は16KBのチャンクに割り当てられ、迅速なアクセスと効果的な格納が可能になります。さらに、より小さいチャンクを使用することで、空き領域の割当てが削減されます。
また、この表では、4種類の異なるイメージ・データを含むXML文書を格納するために、XMLType型の4つの列を定義します。各列は、特定のOracle Multimediaメタデータ・スキーマにバインドされます。各メタデータ・スキーマでは、メタデータ・ドキュメントのデータ・モデルを正確に定義します。これらのスキーマは、データベース作成時に、Oracle XML DBに登録されます。列の定義では、XMLメタデータ・ドキュメントを管理するために、データベースでは構造化された記憶域を使用することを指定します。XMLを管理するために構造化された記憶域を使用することにより、最適化されたメモリー管理、記憶域要件の削減、Bツリー索引およびインプレース更新という利点があります。XML DBの詳細は、『Oracle XML DB開発者ガイド』を参照してください。
インストール時に、このフォト・アルバム・アプリケーションは他のスキーマ・オブジェクトも作成します。これらのスキーマ・オブジェクトには、メタデータ検索を高速にする、CONTEXTテキスト索引およびXMLIndex索引という2種類の索引が含まれます。
CONTEXT型は、イメージに関する記述情報を含むすべての列に対するテキスト索引です。これらの列には、PHOTOS.DESCRIPTIONが含まれます。この列はVARCHAR2データ型で、PHOTOS.METAIPTC、PHOTOS.METAEXIF、PHOTOS.METAXMPおよびPHOTOS.METAORDIMAGEという4つのXMLType列があります。CONTEXTテキスト索引は、ユーザーが写真をキーワードまたは語句で検索できるフォト・アルバム検索機能を実装することによって、メタデータ検索の速度を上げるために使用されます。
CONTEXTテキスト索引は、次の文によって作成されます。(この例では、フォト・アルバム・アプリケーションがSCOTTスキーマにインストールされていると想定します。)
-- Create preference PA_CTXIDX.
ctx_ddl.create_preference('SCOTT.PA_CTXIDX', 'MULTI_COLUMN_DATASTORE');
-- Create a multicolumn datastore.
ctxcols := 'description, ' ||
'SCOTT.photo_album.getClob(METAIPTC), ' ||
'SCOTT.photo_album.getClob(METAEXIF), ' ||
'SCOTT.photo_album.getClob(METAXMP), ' ||
'SCOTT.photo_album.getClob(METAORDIMAGE)';
ctx_ddl.set_attribute( ctxpref, 'COLUMNS', ctxcols );
-- Create the CONTEXT text index.
create index pa_ctx_idx on photos(description)
indextype is ctxsys.context
parameters ( 'DATASTORE SCOTT.PA_CTXIDX' );
テキスト索引の作成および使用については、『Oracle Textアプリケーション開発者ガイド』を参照してください。
XMLIndex索引は、検索対象をXML文書の特定の部分にかぎるだけでなく、ユーザーに特定の種類のイメージ・メタデータのみの検索を許可することで、メタデータ検索の速度を上げるために使用されます。たとえば、次の文では、XMLType型の列に対するexistsNode( )問合せ速度を上げるために、XMLIndex型の3つのテキスト索引を作成します。
create index pa_path_iptc_idx on photos( metaIptc ) indextype is XDB.XMLIndex; create index pa_path_exif_idx on photos( metaExif ) indextype is XDB.XMLIndex; create index pa_path_xmp_idx on photos( metaXMP ) indextype is XDB.XMLIndex;
XMLIndex索引の作成および使用については、『Oracle XML DB開発者ガイド』を参照してください。
インストール中に、PL/SQL Gatewayで定義したとおりに、次のCREATE TABLE文でドキュメント・アップロード表が定義されます。
CREATE TABLE PHOTOS_UPLOAD( name VARCHAR2(256) UNIQUE NOT NULL,
mime_type VARCHAR2(128),
doc_size NUMBER,
dad_charset VARCHAR2(128),
last_updated DATE,
content_type VARCHAR2(128),
blob_content BLOB )
--
-- store BLOBs as SecureFile LOBs
--
LOB(blob_content) STORE AS SECUREFILE;
PL/SQL Gatewayを使用してアップロードされた各イメージは、PHOTOS_UPLOAD表に格納されます。アップロード・プロシージャ(insert_new_photo)は、アップロードされたイメージを、指定されたPHOTOS_UPLOAD表からphotosというフォト・アルバム・アプリケーションの表に自動的に移動します。
サンプル・アプリケーション・ファイルおよびREADME.txtファイルは次のディレクトリにあります。
<ORACLE_HOME>/ord/http/demo/plsqlwtk(LinuxおよびUNIXの場合)
<ORACLE_HOME>\ord\http\demo\plsqlwtk(Windowsの場合)
次の項では、PL/SQLフォト・アルバム・アプリケーションの実行方法について説明します。このサンプル・アプリケーションをインストールおよび使用する場合の追加要件および手順については、README.txtファイルを参照してください。
セットアップ・タスクを完了してフォト・アルバム・アプリケーションを構築し、 README.txtファイルの説明に従ってデータベース・アクセス記述子(DAD)エントリを作成したら、Webブラウザのアドレス・フィールドに次のURLを入力してこのフォト・アルバム・アプリケーションを実行できます。
<protocol><hostname:port-number>/photoalbum
<protocol>フィールドにはhttp://を入力し、<hostname:port-number>フィールドにはHTTPサーバーを実行しているシステムのホスト名とポート番号を入力します。
このフォト・アルバム・アプリケーションを初めて起動した際、その時点でアルバムに格納されているすべてのイメージが表示されます。アプリケーションを初めてインストールした直後は、デフォルトで、フォト・アルバムには何も入っていません。新しい写真をアップロードするには、「Upload new photo」をクリックします。写真の説明およびイメージ・ファイルの名前を入力するか、ディレクトリ内のイメージ・ファイルの位置を参照します。次に、「Upload photo」をクリックします。
新しい写真が追加されたフォト・アルバムの内容が表示されます。縮小イメージをクリックすると、写真が原寸で表示されます。このフォト・アルバム・アプリケーションに縮小イメージではなくテキスト「view image」が表示される場合、アップロードされたイメージのフォーマットがOracle Multimediaで認識されていません。「view image」をクリックすると、原寸イメージが表示されます。
前述の手順に従って、フォト・アルバム・アプリケーションに自由に写真をロードできます。
PL/SQLフォト・アルバム・アプリケーションのユーザー・インタフェースは、一連のWebページで構成されます。これらのWebページを使用して、表3-1に示すタスクを行います。この項では、タスクおよびWebページについて紹介し、この後の項で詳細を説明します。
表3-1 PL/SQLフォト・アルバム・サンプル・アプリケーションの概要
| ユーザー・タスク | Webページ | PL/SQLプロシージャ |
|---|---|---|
フォト・アルバムの参照 3.1.2.1項 |
View album 図3-1 |
view_album例3-1 print_album例3-2 print_image_link例3-3 deliver_media例3-4 |
フォト・アルバムへのイメージの追加 3.1.2.2項 |
Upload photo 図3-2 |
view_upload_formprint_upload_form例3-5 insert_new_photo例3-6 |
キーワードまたは語句でのイメージの検索 3.1.2.3項 |
Search album 図3-3 |
view_album例3-1 print_album例3-2 |
原寸イメージの表示 3.1.2.4項 |
View entry 図3-4 |
view_entry例3-7 print_image_link例3-3 deliver_media例3-4 |
イメージ・メタデータの調査 3.1.2.5項 |
View metadata 図3-5 |
view_metadata例3-8 print_metadata例3-9 |
イメージへの新規XMPメタデータの書込み 3.1.2.6項 |
Write XMP metadata 図3-6 |
write_metadata例3-10 |
特定のメタデータ属性を含むイメージの検索 3.1.2.7項 |
Search metadata 図3-7 |
search_metadata例3-11 |
各Webタスク・ページ上部近くにあるナビゲーション・バーを使用して、このフォト・アルバム・アプリケーションを検索できます。ナビゲーション・バーの一番左のエントリに、現在のWebページ名が表示されます。右には、現在のページからアクセス可能なその他のWebページへのリンクがあります。各Webタスク・ページには、「View album」ページへのリンクがあり、「View album」ページがアプリケーションのホームページになります。
このフォト・アルバム・アプリケーションは、1つのPL/SQLパッケージに編成された、PL/SQLプロシージャおよびファンクションのセットとして実装されています。これらのプロシージャは、いくつかのデータベース機能を組み合せて、アプリケーションを作成します。Oracle Multimediaは、イメージ・データを格納および処理するために使用されます。さらに、イメージからメタデータを抽出し、イメージに新しいメタデータを埋め込むためにも使用されます。XMLType機能は、XMLメタデータ・ドキュメントの格納および処理に使用されます。Oracle Text索引は、2種類のメタデータ検索の速度を向上するために使用されます。最後に、PL/SQL Web Toolkitは、HTMLページを作成し、メディア・コンテンツを配信するために使用されます。
これらのデータベース機能の詳細は、Oracle Application Server JP Documentation Libraryの『Oracle XML DB開発者ガイド』、『Oracle Textアプリケーション開発者ガイド』および『Oracle Application Server PL/SQL Web Toolkitリファレンス』を参照してください。
「View album」ページでのフォト・アルバムの参照 「View album」ページには、フォト・アルバムのすべてのイメージが縮小サイズで表示され、各縮小イメージの下には説明リンクが配置されています。縮小イメージを選択すると、原寸イメージが表示されます。イメージの説明リンクを選択すると、そのイメージのすべてのメタデータが表示されます。「View album」ページは、フォト・アルバム・アプリケーションのホームページです。
「Upload photo」ページでのフォト・アルバムへのイメージの追加 「Upload photo」ページには、新規イメージの説明およびローカル・コンピュータ上のイメージの位置までのディレクトリ・パスを収集するための、簡単なフォームが表示されます。「Upload photo」ボタンをクリックすると、イメージがブラウザによってWebサーバーに送信され、アップロードしたイメージがデータベースに格納されます。
「Search album」ページでのキーワードまたは語句でのイメージの検索 「Search album」ページには、すべてのイメージ・メタデータを対象にしたフルテキスト検索を開始するために、キーワードまたは語句を収集するアルバム検索フォームが表示されます。フォト・アルバム・アプリケーションは、データベースのすべてのイメージについて、特定のキーワードまたは語句を含むメタデータに対する問合せを行います。検索結果は、一連の縮小イメージとして表示されます。アルバム検索フォームは、「View album」ページからも使用できます。
「View entry」ページでの原寸イメージの表示 「View entry」ページには、イメージがアップロードされたときにそのイメージに対して入力された説明テキストとともに、指定した写真の原寸イメージが表示されます。
「View metadata」ページでのイメージ・メタデータの調査 「View metadata」ページには、イメージがアップロードされたときに、イメージから抽出されたすべてのメタデータが表示されます。4種類までのメタデータを表示できます。
「Write XMP metadata」ページでのイメージへの新規XMPメタデータの書込み 「Write XMP metadata」ページには、5つのメタデータ属性に対する入力を収集するためのフォームが表示されます。これらの属性は、バイナリ・イメージに埋め込まれたXML文書に書式設定されます。新規XMPメタデータは、既存のすべてのXMPメタデータを上書きします。
「Search metadata」での特定のメタデータ属性を含むイメージの検索 「Search metadata」ページでは、メタデータの拡張検索に対する入力を収集します。検索するメタデータの種類を指定できます。特定の文書に含まれる指定したタグに検索を限定することもできます。検索結果は、一連の縮小イメージとして表示されます。
このフォト・アルバム・アプリケーションのホームページである「View album」では、フォト・アルバムの内容を縮小イメージで4列に表示します。また、各縮小イメージは、「View entry」ページにもリンクされています。縮小イメージのリンクをクリックすると、アプリケーションは、「View entry」ページに原寸イメージで表示されます。「View album」ページの各縮小イメージの下には、イメージがアルバムにアップロードされたときに入力されたイメージの説明があります。この説明も「View metadata」ページにリンクされていて、「View metadata」ページでは、この写真に対するすべてのメタデータを調べることができます。
「View album」ページの上部付近には、フォト・アルバムのすべてのメタデータに対してフルテキスト検索を行うための、ユーザー入力が可能な長方形のテキスト入力フィールドがあります。テキスト・フィールドの右にある「Search」ボタンで、検索を開始します。検索結果は、「Search album」ページに表示されます。詳細は3.1.2.3項を参照してください。
「View album」ページ上部には、ナビゲーション・バーがあり、他のフォト・アルバム・ページへのリンクが含まれています。「View album」ページから、「Search metadata」ページまたは「Upload photo」ページに移動できます。これらのページについては、3.1.2.7項および3.1.2.2項を参照してください。
図3-1に、5つのイメージがアップロードされているアルバムの「View album」ページを示します。
PL/SQLプロシージャview_album、print_album、print_image_linkおよびdeliver_mediaは、「View album」ページを実装する主要なアプリケーション・コンポーネントです。view_albumプロシージャは、1つのオプションの引数をとるパブリック・プロシージャです。デフォルトでは、引数はNULL値です。「Search album」ページのテキスト入力フィールドに入力した文字列を、引数にすることもできます。検索引数がNULLの場合、SELECT文は、photos表のすべてのエントリからid列、description列およびthumb列を取得します。検索文字列がNULLでない場合、SELECT文はCONTAINS演算子を使用して、検索文字列と一致するメタデータを持つイメージに結果セットを制限します。3.1項では、アプリケーションで、PHOTOS.DESCRIPTION列に加えて4つのXMLType列(PHOTOS.METAIPTC列、PHOTOS.METAEXIF列、PHOTOS.METAXMP列およびPHOTOS.METAORDIMAGE列)に対して複数列テキスト索引を作成する方法を説明します。
例3-1に、view_albumプロシージャの関連するいくつかのコード行を示します。
例3-1 view_albumプロシージャ
--
-- no search criteria so fetch all entries
--
IF search IS NULL THEN
OPEN album_cur FOR
SELECT id, description, thumb
FROM photos
ORDER BY id;
print_album( album_cur, 'The photo album is empty.' );
CLOSE album_cur;
ELSE
-- -- use the full-text index to select entries matching the search criteria
--
OPEN album_cur FOR
SELECT id, description, thumb
FROM photos
WHERE CONTAINS( description, trim(search) ) > 0
ORDER BY id;
print_album( album_cur, 'No photos were found.' );
CLOSE album_cur;
END IF;
SELECT文はカーソル変数album_curにバインドされ、プロシージャprint_albumに渡されます。このプロシージャはHTML出力を作成します。
print_albumプロシージャは、出力を4列の表に書式設定するHTMLタグを作成するために、PL/SQL Web ToolkitのHTPおよびHTFパッケージを使用します。表の各セルには、2つのリンクまたは2つのアンカー・タグが含まれます。1つ目のリンクは、「View entry」ページへのリンクで、イメージを原寸で表示します。このアンカーは、PHOTO_ALBUM.VIEW_ENTRYによって実装され、entry_idを問合せ文字列の入力引数として渡します。縮小イメージの長さが0(ゼロ)以外の場合、アンカー・リンクのコンテンツ(縮小イメージ)であるHTML <img>タグを作成するために、print_image_linkプロシージャがコールされます。文字列thumbおよびentry_idは、イメージの説明、縮小イメージの高さおよび幅とともに、print_image_linkプロシージャに渡されます。これらの値は<img>タグの作成に使用されます。
イメージがOracle Multimediaでサポートしていないフォーマットの場合、アプリケーションは、イメージの縮小イメージを作成することができません。この場合、アンカー・リンクのコンテンツはテキストのビュー・イメージになります。
例3-2に、print_albumプロシージャの関連するいくつかのコード行を示します。
例3-2 print_albumプロシージャ
-- escape the description text
sc_description := htf.escape_sc( entry.description );
--
-- Display the thumb-nail image as an anchor tag which can be used
-- to display the full-size image. If the image format isn't
-- supported by interMedia, then a thumb-nail wouldn't have been
-- produced when the image was uploaded, so use the text '[view
-- image]' instead of the thumb-nail.
--
htp.print( '<td headers="c' || colIdx || '" align="center" >
<a href="PHOTO_ALBUM.VIEW_ENTRY?entry_id=' ||
entry.id || '">' );
IF entry.thumb.contentLength > 0
THEN
print_image_link( 'thumb', entry.id, sc_description,
entry.thumb.height, entry.thumb.width );
ELSE
htp.prn( '[view image]' );
END IF;
htp.print( '</a>' );
-- Create link to the metadata
htp.prn('<br>');
htp.anchor( curl=>'PHOTO_ALBUM.VIEW_METADATA?entry_id=' || entry.id,
ctext=>sc_description );
htp.prn('</td>');
プロシージャprint_image_linkは、height引数およびwidth引数を使用して、<img>タグのheight属性およびwidth属性に移入します。description引数は、alt属性用のテキストの作成に使用されます。description引数が空の場合は、デフォルトの文字列が構成されます。最後に、2つの問合せ文字列の引数mediaおよびentry_idを使用して、src属性がURL PHOTO_ALBUM.DELIVER_MEDIAに設定されます。media引数は、配信されるイメージが縮小イメージか原寸イメージかを制御します。entry_id引数は、配信されるイメージを指定します。
例3-3に、print_image_linkプロシージャの関連するいくつかのコード行を示します。
例3-3 print_image_linkプロシージャ
-- add height and width to tag if non zero
IF height > 0 AND width > 0 THEN
attributes := attributes || ' height=' || height || ' width=' || width;
END IF;
-- create an alt text if none given
IF alt IS NULL THEN
IF type = 'thumb' THEN
alt2 := 'thumb-nail image ';
ELSE
alt2 := 'full-size image ';
END IF;
alt2 := alt2 || 'for album entry ' || entry_id;
ELSE
alt2 := alt;
END IF;
htp.img( curl=>'PHOTO_ALBUM.DELIVER_MEDIA?media=' || type ||
ampersand || 'entry_id=' || entry_id,
calt=>alt2, cattributes=>attributes );
プロシージャdeliver_mediaは、データベースからイメージ・コンテンツをフェッチします。If-Modified-Since HTTPリクエスト・ヘッダーが、イメージの最終変更時刻と比較されます。イメージが変更されていない場合、ブラウザでキャッシュからイメージを表示できるという内容のレスポンスが送信されます。イメージが変更されている場合は、イメージのMIMEタイプおよび最終変更時刻が、イメージ・コンテンツとともにWebサーバーに送信されます。
例3-4に、deliver_mediaプロシージャの関連するいくつかのコード行を示します。
例3-4 deliver_mediaプロシージャ
--
-- Fetch the thumb-nail or full-size image from the database.
--
IF media = 'thumb'
THEN
SELECT thumb INTO local_image FROM photos WHERE id = entry_id;
ELSE
SELECT image INTO local_image FROM photos WHERE id = entry_id;
END IF;
--
-- Check update time if browser sent If-Modified-Since header
--
IF ordplsgwyutil.cache_is_valid( local_image.getUpdateTime() )
THEN
owa_util.status_line( ordplsgwyutil.http_status_not_modified );
RETURN;
END IF;
--
-- Set the MIME type and deliver the image to the browser.
--
owa_util.mime_header( local_image.mimeType, FALSE );
ordplsgwyutil.set_last_modified( local_image.getUpdateTime() );
owa_util.http_header_close();
IF owa_util.get_cgi_env( 'REQUEST_METHOD' ) <> 'HEAD' THEN
wpg_docload.download_file( local_image.source.localData );
END IF;
「Upload photo」ページは、フォト・アルバムへの新規イメージの追加に使用されます。このページには、2つのテキスト入力フィールドがあるフォームが表示されます。「Description:」フィールドには、イメージを説明する単語または短い語句を任意に入力できます。 「File name:」フィールドには、イメージ・ファイルの名前を入力するか、「Browse」をクリックして、アップロードするイメージの位置を検索します。「File name:」フィールドの下にある「Upload photo」ボタンを押すと、アップロード操作が開始されます。イメージが正常にアップロードされると、「View album」ページが表示されます。3.1.2.1項に示すように、「View album」ページからフォト・アルバムの内容を表示できます。
「Upload photo」ページ上部には、ナビゲーション・バーがあり、他のフォト・アルバム・ページへのリンクが含まれています。「Upload photo」ページから、「View album」ページに戻るか、「Search metadata」ページを選択できます。これらのページについては、3.1.2.1項および3.1.2.7項を参照してください。
図3-2に、すべてのフィールドが入力されている「Upload photo」ページを示します。
PL/SQLプロシージャview_upload_form、print_upload_formおよびinsert_new_photoは、「Upload photo」ページを実装する主要なアプリケーション・コンポーネントです。view_upload_formおよびprint_upload_formは、表示されるHTMLページを作成します。ページには、例3-5に示すformタグが含まれます。フォームのターゲットは、PHOTO_ALBUM.INSERT_NEW_PHOTOです。
例3-5に、print_upload_formプロシージャの関連するいくつかのコード行を示します。
例3-5 print_upload_formプロシージャ
<form action="PHOTO_ALBUM.INSERT_NEW_PHOTO" method="post" enctype="multipart/form-data"> database.
プロシージャinsert_new_photoは、フォームを受信し、入力を処理し、データベースに新規イメージを格納します。
最初に、insert_new_photoが、ファイル名がアップロード・フォームに入力されていることを確認します。イメージ・コンテンツのサイズ、MIMEタイプおよびBLOBロケータがドキュメント・アップロード表から選択され、イメージの長さが0(ゼロ)でないかを確認します。descriptionフィールドが空白の場合、ファイル名を使用して説明が作成されます。
次に、ORDSYS.ORDIMAGE.INIT( )ファンクションをコールし、photos表に格納される新しい行のthumbおよびimage ORDImageオブジェクト型列を空のBLOBで初期化します。SQLのSELECT FOR UPDATE文によって、新しく初期化された縮小イメージおよび原寸イメージのオブジェクト型列が更新対象としてフェッチされます。DBMS_LOB.COPY操作によって、アップロード表からimage ORDImageオブジェクト型列にイメージがロードされます。
ORDImageオブジェクト・メソッドのsetProperties( )がイメージを読み込み、イメージ・オブジェクト属性を設定します。一部のイメージ・フォーマットをインラインで表示できないブラウザもあるため、このサンプル・アプリケーションでは、get_preferred_formatファンクションをコールすることで、BMPフォーマットのイメージをJPEG(色が8ビットを超えるイメージ)またはGIFF(色が9ビット未満のイメージ)イメージ・フォーマットに変換します。processCopy( )操作が原寸イメージに実行され、縮小イメージが作成されます。
ORDImageオブジェクトのgetMetadata( )メソッドがコールされ、サポートされているすべての種類のイメージ・メタデータが抽出されます。ドキュメントを正しい列に格納できるメタデータの型を判断するために、リターン・ベクトルの各XML文書のルート要素が調べられます。
その後、SQL UPDATE文が、原寸イメージ、縮小イメージおよびメタデータ・ドキュメントをデータベースに格納します。プロシージャsync_indexesが、テキスト索引を強制的に更新するためにコールされます。最後に、フォーム・データの入力内容が、ドキュメント・アップロード表から削除されます。アップロードが成功したことを示すメッセージがブラウザに表示され、ブラウザは「View album」ページにリダイレクトされます。
例3-6に、insert_new_photoプロシージャの関連するいくつかのコード行を示します。
例3-6 insert_new_photoプロシージャ
--
-- Make sure a file name has been provided. If not, display an error
-- message, then re-display the form.
--
IF new_photo IS NULL OR LENGTH( new_photo ) = 0
THEN
print_page_header;
print_error( 'Please supply a file name.' );
print_upload_form;
print_page_trailer( TRUE );
return;
END IF;
--
-- Get the length, MIME type and the BLOB of the new photo from the
-- upload table.
--
SELECT doc_size,
mime_type,
blob_content
INTO upload_size,
upload_mime_type,
upload_blob
FROM photos_upload
WHERE name = new_photo;
--
-- Make sure we have a valid file.
--
IF upload_size = 0
THEN
print_page_header;
print_heading( 'Error message' );
htp.print( '<hr size="-1"><p>Please supply a valid image file.</p>' );
print_upload_form;
print_page_trailer( TRUE );
return;
END IF;
--
-- If the description is blank, then use the file name.
--
IF c_description IS NULL
THEN
c_description := new_photo;
pos := INSTR( c_description, '/', -1 );
IF pos > 0
THEN
c_description := SUBSTR( c_description, pos + 1 );
END IF;
c_description := SUBSTR( 'Image from file: ' ||
c_description || '.', 1, 40 );
END IF;
--
-- Insert a new row into the table, returning the newly allocated sequence
-- number.
INSERT INTO photos ( id, description, metaExif, metaIPTC, metaXMP,
image, thumb )
VALUES ( photos_sequence.nextval, c_description, NULL, NULL, NULL,
ORDSYS.ORDIMAGE.INIT(), ORDSYS.ORDIMAGE.INIT() )
RETURN id
INTO new_id;
--
-- Fetch the newly initialized full-size and thumb-nail image objects.
--
SELECT image,
thumb
INTO new_image,
new_thumb
FROM photos
WHERE id = new_id
FOR UPDATE;
--
-- Load the photo from the upload table into the image object.
--
DBMS_LOB.COPY( new_image.source.localData, upload_blob, upload_size );
new_image.setLocal();
--
-- Set the properties. If the image format is not recognized, then
-- the exception handler will set the MIME type and length from the
-- upload table.
--
BEGIN
new_image.setProperties();
EXCEPTION
WHEN OTHERS THEN
new_image.contentLength := upload_size;
new_image.mimeType := upload_mime_type;
END;
--
-- Some image formats are supported by interMedia but may not be able
-- to be displayed in-line by a browser. The BMP format is one example.
-- Convert the image to a GIF or JPEG based on number of colors in the
-- image.
--
IF new_image.contentFormat IS NOT NULL AND
( new_image.mimeType = 'image/bmp' OR
new_image.mimeType = 'image/x-bmp' )
THEN
BEGIN
new_image.process(
'fileFormat=' ||
get_preferred_format( new_image.contentFormat ) );
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END IF;
--
-- Try to copy the full-size image and process it to create the thumb-nail.
-- This may not be possible if the image format is not recognized.
--
BEGIN
new_image.processCopy( thumb_scale, new_thumb );
EXCEPTION
WHEN OTHERS THEN
new_thumb.deleteContent();
new_thumb.contentLength := 0;
END;
--
-- fetch the metadata and sort the results
--
BEGIN
metav := new_image.getMetadata( 'ALL' );
FOR i IN 1..metav.count() LOOP
meta_root := metav(i).getRootElement();
CASE meta_root
WHEN 'ordImageAttributes' THEN xmlORD := metav(i);
WHEN 'xmpMetadata' THEN xmlXMP := metav(i);
WHEN 'iptcMetadata' THEN xmlIPTC := metav(i);
WHEN 'exifMetadata' THEN xmlEXIF := metav(i);
ELSE NULL;
END CASE;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
--
-- Update the full-size and thumb-nail images in the database.
-- Update metadata columns
--
UPDATE photos
SET image = new_image,
thumb = new_thumb,
metaORDImage = xmlORD,
metaEXIF = xmlEXIF,
metaIPTC = xmlIPTC,
metaXMP = xmlXMP
WHERE id = new_id;
-- -- update the text indexes
-- sync_indexes;
--
-- Delete the row from the upload table.
--
DELETE FROM photos_upload WHERE name = new_photo;
COMMIT;
--
-- Redirect browser to display full album.
-- print_page_header(
'<meta http-equiv="refresh" content="2;url=PHOTO_ALBUM.VIEW_ALBUM">' );
print_heading( 'Photo successfully uploaded into photo album' );
「View album」ページおよび「Search album」ページを使用して、フォト・アルバムに格納されているメタデータのキーワード検索または語句検索を実行できます。いずれかのページで、「Full text search:」テキスト入力フィールドにキーワードまたは語句を入力し、「Search」をクリックします。このフォト・アルバム・アプリケーションは、CONTEXTテキスト索引を使用して、入力したテキストを含むメタデータを持つイメージを検索します。検索に成功すると、一致したイメージの縮小イメージが4列の表で表示されます。縮小イメージを選択して原寸イメージを表示するか、縮小イメージの下にある説明リンクを選択してイメージのメタデータを表示します。検索に失敗すると、「No photos were found」というメッセージが表示されます。
「Search album」ページ上部には、ナビゲーション・バーがあり、他のフォト・アルバム・ページへのリンクが含まれています。「Search album」ページから、「View album」ページに戻るか、「Search metadata」ページまたは「Upload photo」ページを選択します。これらのページについては、3.1.2.1項、3.1.2.7項および3.1.2.2項をそれぞれ参照してください。
図3-3に、検索操作に成功し、結果が表示されている「Search album」ページを示します。
フォト・アルバムのフルテキスト検索は、view_albumおよびprint_albumプロシージャによって実装されます。これらのプロシージャについては、3.1.2.1項を参照してください。
縮小イメージを選択すると、アプリケーションによって「View entry」ページが表示されます。このページに、イメージの説明および原寸イメージが表示されます。
「View entry」ページ上部には、ナビゲーション・バーがあり、他のフォト・アルバム・ページへのリンクが含まれています。「View entry」ページから、「View album」ページに戻るか、「View metadata」ページ、「Write metadata」ページ、「Search metadata」ページまたは「Upload photo」ページのいずれかを選択します。これらのページについては、3.1.2.1項、3.1.2.5項、3.1.2.6項、3.1.2.7項および3.1.2.2項をそれぞれ参照してください。
図3-4に、イメージの説明および原寸イメージが表示されている「View entry」ページを示します。
PL/SQLプロシージャview_entry、print_image_linkおよびdeliver_mediaは、「View entry」ページを実装する主要なアプリケーション・コンポーネントです。プロシージャview_entryは、1つのパラメータentry_idをとります。このパラメータは、photos表でイメージを一意に検出します。説明およびイメージ・オブジェクトは、photos表からフェッチされます。プロシージャprint_image_linkは、HTML <img>タグを作成し、プロシージャdeliver_mediaをコールしてイメージ・コンテンツをフェッチします。print_image_linkおよびdeliver_mediaプロシージャの詳細は、3.1.2.1項を参照してください。
例3-7に、view_entryプロシージャの関連するいくつかのコード行を示します。
例3-7 view_entryプロシージャ
--
-- Fetch the row.
--
BEGIN
SELECT htf.escape_sc(description), image
INTO sc_description, photo
FROM photos
WHERE id = entry_id;
EXCEPTION
WHEN no_data_found THEN
print_error( 'Image <b>' || htf.escape_sc(entry_id) ||
'</b> was not found.</p>' );
print_page_trailer( TRUE );
return;
END;
print_image_link( 'image', entry_id, sc_description, photo.height, photo.width );
「View metadata」ページを使用して、指定したイメージのすべてのメタデータを調べることができます。通常、「View album」ページで縮小イメージの下にある説明リンクを選択して、このページにアクセスします。ナビゲーション・バーから「View metadata」リンクを選択しても、このページにアクセスできます。「View metadata」ページには、イメージの縮小イメージが表示されます。縮小イメージの右に、このイメージのメタデータ・ドキュメントのリストがあります。リストの各エントリは、「View metadata」ページのメタデータ・ドキュメントにリンクされています。
「View metadata」ページ上部には、ナビゲーション・バーがあり、他のフォト・アルバム・ページへのリンクが含まれています。「View metadata」ページから、「View album」ページに戻るか、「View entry」ページ、「Write metadata」ページ、「Search metadata」ページまたは「Upload photo」ページのいずれかを選択します。これらのページについては、3.1.2.1項、3.1.2.4項、3.1.2.6項、3.1.2.7項および3.1.2.2項をそれぞれ参照してください。
図3-5に、イメージの2種類のメタデータ(XMPおよびORDIMAGE)が表示されている「View metadata」ページを示します。
図3-5 アップロードしたイメージのメタデータが表示されている「View metadata」ページ

PL/SQLプロシージャview_metadataおよびprint_metadataは、「View metadata」ページを実装する主要なアプリケーション・コンポーネントです。プロシージャview_metadataには、引数entry_idが渡されます。この引数は、photos表でイメージを一意に識別します。SELECT文は、指定されたエントリのすべてのXMLtypeのメタデータ列を検索します。メタデータ列がNULLでない場合、HTML <pre>タグ内でXML文書を表示するためにプロシージャprint_metadataがコールされます。
例3-8に、view_metadataプロシージャの関連するいくつかのコード行を示します。
例3-8 view_metadataプロシージャ
--
-- Fetch the row.
--
SELECT metaOrdImage, metaEXIF, metaIPTC, metaXMP
INTO metaO, metaE, metaI, metaX
FROM photos
WHERE id = entry_id;
-- display the EXIF metadata
IF metaE IS NOT NULL THEN
htp.print( '<span class="bigBlue" id="exifMetadata">EXIF</span>' );
htp.print( '<br><pre>' );
print_metadata( metaE ); htp.print( '</pre>' );
END IF;
print_metadataプロシージャは、XMLType文書を引数として受け入れます。CLOBとして文書にアクセスするために、getClobVal( )メソッドが使用されます。CLOBのコンテンツは、ループに読み込まれ、htp.printsプロシージャを使用してHTMLページに書式設定されます。htp.printsプロシージャは、「<」および「>」文字を無視するため、Webブラウザによって適切にレンダリングされます。
例3-9に、print_metadataプロシージャの関連するいくつかのコード行を示します。
「Write XMP metadata」ページを使用して、イメージに新規XMPメタデータを書き込んだり、既存のXMPメタデータを置換することができます。Oracle Multimediaでは、XMPメタデータの書込みのみをサポートしています。「View entry」ページまたは「View metadata」ページのいずれかからナビゲーション・バーの「Write metadata」リンクを選択することで、「Write XMP metadata」ページにアクセスできます。
「Write XMP metadata」ページには、変更するイメージの縮小イメージが表示されます。このページには、次の5つのテキスト入力フィールドのメタデータ属性を収集するための入力フォームも表示されます。
Title:写真のタイトルを指定します。
Creator:撮影者の名前を入力します。このフィールドへの入力は任意です。
Date:撮影日を入力します。このフィールドへの入力は任意です。
Description:写真のテーマなどの説明を入力します。このフィールドへの入力は任意です。
Copyright:写真を撮影した月および年を入力します。このフィールドへの入力は任意です。
「Write it!」をクリックし、アプリケーションにフォームを送信して、イメージにXMP形式でメタデータを埋め込みます。
「Write XMP metadata」ページ上部には、ナビゲーション・バーがあり、他のフォト・アルバム・ページへのリンクが含まれています。「Write XMP metadata」ページから、「View album」ページに戻るか、「View entry」ページ、「View metadata」ページ、「Search metadata」ページまたは「Upload photo」ページのいずれかを選択します。これらのページについては、3.1.2.1項、3.1.2.4項、3.1.2.5項、3.1.2.7項および3.1.2.2項をそれぞれ参照してください。
図3-6に、イメージについてのエントリが入力されている「Write XMP metadata」ページを示します。
図3-6 アップロードしたイメージについてのXMPメタデータが入力されている「Write XMP metadata」ページ

PL/SQLプロシージャwrite_metadataは、ブラウザからフォーム入力フィールドを受信します。プロシージャは、Oracle Multimedia XMPスキーマhttp://xmlns.oracle.com/ord/meta/xmpで有効なXML文書を文字列バッファとして作成します。文字列バッファは、XMLTypeオブジェクトの作成に使用されます。
SELECT FOR UPDATE文は、変更するイメージを取得します。Oracle MultimediaのputMetadata( )メソッドが、XML文書をイメージに埋め込むためにコールされます。変更されたイメージは、photos表に再度格納されます。最後に、プロシージャsync_indexesが、テキスト索引を更新するためにコールされます。
例3-10に、write_metadataプロシージャの関連するいくつかのコード行を示します。
例3-10 write_metadataプロシージャ
-- Create the XMP packet it must be schema valid
-- to "http://xmlns.oracle.com/ord/meta/xmp"
-- and contain an <RDF> element. This example uses
-- the Dublin Core schema as implemented by Adobe XMP
buf := '<xmpMetadata xmlns="http://xmlns.oracle.com/ord/meta/xmp"
xsi:schemaLocation="http://xmlns.oracle.com/ord/meta/xmp
http://xmlns.oracle.com/ord/meta/xmp"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title>' || htf.escape_sc(title) || '</dc:title>';
IF c_creator IS NOT NULL THEN
buf := buf || '<dc:creator>' || htf.escape_sc(c_creator)
|| '</dc:creator>';
END IF;
IF c_date IS NOT NULL THEN
buf := buf || '<dc:date>' || htf.escape_sc(c_date)
|| '</dc:date>';
END IF;
IF c_description IS NOT NULL THEN
buf := buf || '<dc:description>' || htf.escape_sc(c_description)
|| '</dc:description>';
END IF;
IF c_copyright IS NOT NULL THEN
buf := buf || '<dc:copyright>' || htf.escape_sc(c_copyright)
|| '</dc:copyright>';
END IF;
buf := buf || '
</rdf:Description>
</rdf:RDF>
</xmpMetadata>';
xmp := XMLType.createXML(buf, 'http://xmlns.oracle.com/ord/meta/xmp');
-- -- select image for update
-- description is selected to force update of CTX index
--
SELECT image, description
INTO img, des
FROM photos
WHERE id = entry_id
FOR UPDATE;
--
-- write the metadata
--
img.putMetadata( xmp, 'XMP' );
--
-- save updated image and new metadata to table
-- description updated to force update of CTX index
--
UPDATE photos
SET image = img,
metaXMP = xmp,
description = des
WHERE id = entry_id;
-- update the text indexes
sync_indexes;
例3-10に示す入力データによって、メタデータは次のようにイメージに格納されます。
<xmpMetadata xmlns="http://xmlns.oracle.com/ord/meta/xmp"
xsi:schemaLocation="http://xmlns.oracle.com/ord/meta/xmp
http://xmlns.oracle.com/ord/meta/xmp"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title>Story time</dc:title>
<dc:creator>father</dc:creator>
<dc:date>July 4, 2001</dc:date>
<dc:description>family reading</dc:description>
<dc:copyright>mother</dc:copyright>
</rdf:Description>
</rdf:RDF>
</xmpMetadata>
「Search metadata」ページを使用して、メタデータ・ドキュメント内の特定のタグに検索を限定するだけでなく、特定のメタデータの型を検索することもできます。「Search metadata」ページには、任意のフォト・アルバム・アプリケーションWebページのナビゲーション・バーから「Search metadata」リンクを選択することによってアクセスできます。
「Search metadata」ページには、検索の実行方法を定義するための4つのフィールドがあるフォームが表示されます。「Search in metadata:」フィールドのプルダウン・メニューを使用して、検索するメタデータの型(EXIF、IPTCまたはXMP)を選択します。このフィールドを変更すると、フィールド「Search in tag:」および「Search method:」が、検索するメタデータの型に適した値に初期化されます。
「Search in tag:」フィールドのドロップダウン・リストを使用して、メタデータ・ドキュメント内の特定のXML要素に検索を限定します。選択したメタデータの型に適した要素名が、リストに移入されます。「--Any tag--」が表示された場合は、ドキュメント・タイプにあるすべての要素が検索されます。メタデータの型にXMPを選択すると、親RDF要素内のDescription要素に検索が限定されます。メタデータ・ドキュメントが適切に構成されている場合、このフィールドで「RDF/Description」を選択すると、XMPドキュメント内の関連するすべてのメタデータが検索されます。
「Search method:」フィールドで、ラジオ・ボタン「Contains」を選択すると、検索対象が、検索文字列を含む要素に特定されます。ラジオ・ボタン「Equal」を選択すると、検索対象が、検索文字列と完全に一致する要素の値に特定されます。XMPメタデータの検索に関しては、「Contains」検索方法のみを実行できます。
最後に、「Search string:」フィールドにキーワードまたは語句を入力して、「Search」をクリックします。検索に成功すると、一致したイメージの縮小イメージが4列の表で表示されます。縮小イメージをクリックすると、イメージが原寸で表示されます。または、縮小イメージの下にある説明リンクを選択すると、イメージのメタデータが表示されます。検索に失敗すると、「No photos matched the search criteria.」というメッセージが表示されます。
「Search metadata」ページ上部には、ナビゲーション・バーがあり、他のフォト・アルバム・ページへのリンクが含まれています。「Search metadata」ページから、「View album」ページに戻るか、「Upload photo」ページを選択します。これらのページについては、3.1.2.1項および3.1.2.2項を参照してください。
図3-7に、サンプルの検索条件が含まれ、検索操作に成功して結果が表示されている「Search metadata」ページを示します。
図3-7 アップロードしたイメージに対する検索実行後の「Search metadata」ページ

PL/SQLプロシージャsearch_metadataは、Webブラウザからフォーム入力フィールドを受信します。検索パラメータは、希望するメタデータを含むイメージを検索するための問合せ作成に使用されます。検索は、SQL EXISTSNODE演算子を使用して実行されます。EXISTSNODE演算子は、特定の検索述語に一致するコンテンツをXML文書で検索するために使用されます。文書で検索が一致した場合は1が、一致しない場合は0が演算子によって戻されます。EXISTSNODE演算子は3つの引数をとります。1つ目の引数は、XMLType列の名前です。このアプリケーションでは、「Search in metadata:」フィールドのプルダウン・メニューで選択したメタデータの型によって、検索列が決定されます。2つ目の引数は、検索するコンテンツおよび一致の評価方法を指定するXPATH式です。「Search in tag:」フィールドおよび「Search method:」フィールドは、XPATH式の作成に使用されます。3つ目の引数は、文書およびXPATH式の処理に使用される、XMLネームスペースを決定するための文字列です。
たとえば、search_metadataプロシージャが、キーワード「farm」と完全一致するcaptionタグをIPTCメタデータで検索するように指定された入力を受信したとします。この検索を実行するための問合せは、次のとおりです。
SELECT id, description, thumb
FROM photos
WHERE EXISTSNODE( metaIptc,
'/iptcMetadata//caption="farm"',
'xmlns:ora="http://xmlns.oracle.com/xdb" ' ||
'xmlns="http://xmlns.oracle.com/ord/meta/iptc"' ) = 1;
EXISTSNODE演算子の2つ目の引数である'/iptcMetadata//caption="farm"は、ルート要素<iptcMetadata>以下のすべての<caption>要素に対する検索を指定します。ここで<caption>コンテンツは「farm」と一致します。
EXISTSNODE式の詳細は、『Oracle XML DB開発者ガイド』を参照してください。contains( )テキスト検索演算子の詳細は、『Oracle Textアプリケーション開発者ガイド』を参照してください。
例3-11に、search_metadataプロシージャの関連するいくつかのコード行を示します。
例3-11 search_metadataプロシージャ
-- set up search variables for EXIF documents
IF mtype = 'exif' THEN
IF op = 'equals' THEN
xpath := '/exifMetadata//' || tag || '="' || c_search || '"';
ELSE -- default to contains
xpath := '/exifMetadata//' || tag ||
'[ora:contains(text(), "' || c_search || '")>0]';
END IF;
nspace := 'xmlns:ora="http://xmlns.oracle.com/xdb" ' ||
'xmlns="http://xmlns.oracle.com/ord/meta/exif"';
OPEN album_cur FOR
SELECT id, description, thumb
FROM photos
WHERE existsnode( metaExif, xpath, nspace ) = 1;
-- set up search variables for IPTC documents
ELSIF mtype = 'iptc' THEN
IF op = 'equals' THEN
xpath := '/iptcMetadata//' || tag || '="' || c_search || '"';
ELSE -- default to contains
xpath := '/iptcMetadata//' || tag ||
'[ora:contains(text(), "' || c_search || '")>0]';
END IF;
nspace := 'xmlns:ora="http://xmlns.oracle.com/xdb" ' ||
'xmlns="http://xmlns.oracle.com/ord/meta/iptc"';
OPEN album_cur FOR
SELECT id, description, thumb
FROM photos
WHERE existsnode( metaIptc, xpath, nspace ) = 1;
-- set up search variables for XMP documents
ELSIF mtype = 'xmp' THEN
-- default to contains
xpath := '/xmpMetadata/rdf:RDF/rdf:Description/*[ora:contains(text(), "'
|| c_search || '")>0]';
-- add rdf namespace prefix
nspace := 'xmlns:ora="http://xmlns.oracle.com/xdb" ' ||
'xmlns="http://xmlns.oracle.com/ord/meta/xmp" ' ||
'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"';
OPEN album_cur FOR
SELECT id, description, thumb
FROM photos
WHERE existsnode( metaXMP, xpath, nspace ) = 1;
ELSE
errorMsg := 'Search domain is invalid: ' || htf.escape_sc(mtype);
END IF;
print_search_form( mtype, tag, op, c_search );
htp.print('<hr size="-1">');
print_album( album_cur, 'No photos matched the search criteria.' );
Oracle Multimedia Javaサーブレット・フォト・アルバム・サンプル・アプリケーションでは、Oracle Multimedia Servlets and JSP Java APIを使用してマルチメディア・データをデータベースにアップロードおよびデータベースから取得する方法を示します。ユーザーは、このフォト・アルバム・アプリケーションにアクセスして、各写真の縮小イメージを含むフォト・アルバムの内容の表示、任意の写真の原寸イメージの表示、およびアルバムへの新しい写真のアップロードを行います。
このフォト・アルバム・アプリケーションでは、Oracle Multimedia Imageオブジェクト型を使用して、Oracle Databaseに格納されたメディア・データをアップロードおよび取得する方法を示します。
このフォト・アルバム・アプリケーションをインストールすると、photosという名前の表およびphotos_sequenceという名前の順序が作成されます。
photos表は、CREATE TABLE文で次のとおり作成されています。
CREATE TABLE photos( id NUMBER PRIMARY KEY,
description VARCHAR2(40) NOT NULL,
location VARCHAR2(40),
image ORDSYS.ORDIMAGE,
thumb ORDSYS.ORDIMAGE )
--
-- store full-size images and thumbnail images as SecureFile LOBs
--
LOB(image.source.localdata) STORE AS SECUREFILE
LOB(thumb.source.localdata) STORE AS SECUREFILE;
image列およびthumb列のデータ型が、それぞれ原寸イメージおよび生成される縮小イメージを格納するOracle Multimedia Imageオブジェクト型として定義されていることに注意してください。
photos_sequence順序は、CREATE SEQUENCE文で次のとおり作成されています。
CREATE SEQUENCE photos_sequence;
サンプル・アプリケーション・ファイルおよびREADME.txtファイルは次のディレクトリにあります。
<ORACLE_HOME>/ord/http/demo/servlet(LinuxおよびUNIXの場合)
<ORACLE_HOME>\ord\http\demo\servlet(Windowsの場合)
次の項では、Javaサーブレット・フォト・アルバム・アプリケーションの実行方法について説明します。このサンプル・アプリケーションをインストールおよび使用する場合の追加要件および手順については、README.txtファイルを参照してください。
セットアップ・タスクを完了してJavaサーブレット・フォト・アルバム・アプリケーションを構築したら、Webブラウザのアドレス・フィールドに次のURLを入力してこのフォト・アルバム・アプリケーションを実行できます。
Oracle Application ServerまたはOracle Databaseをデフォルト設定でインストールしている場合
<protocol><hostname:port-number>/servlet/PhotoAlbumServlet
WindowsにTomcat 3.2をデフォルト設定でインストールしている場合
<protocol><hostname:port-number>/examples/servlet/PhotoAlbumServlet
<protocol>フィールドにはhttp://を入力し、<hostname:port-number>フィールドにはHTTPサーバーを実行しているシステムのホスト名とポート番号を入力します。
このフォト・アルバム・アプリケーションを初めて起動した際、その時点でアルバムに格納されているすべてのイメージが表示されます。アプリケーションを初めてインストールした直後は、デフォルトで、フォト・アルバムには何も入っていません。新しい写真をアップロードするには、「Upload new photo」をクリックします。写真の説明と撮影場所を入力し、イメージ・ファイルの名前を入力して(またはディレクトリ内のイメージ・ファイルの位置を参照して)、「Upload photo」をクリックします。新しい写真が追加されたフォト・アルバムの内容が表示されます。縮小イメージをクリックすると、写真が原寸で表示されます。
このフォト・アルバム・アプリケーションに縮小イメージではなくテキスト「view image」が表示される場合、アップロードされたイメージのフォーマットがOracle Multimediaで認識されていません。「view image」をクリックすると、原寸イメージが表示されます。
前述の手順に従って、フォト・アルバム・アプリケーションに自由に写真をロードできます。
Java Servletサーブレット・フォト・アルバム・アプリケーションでは、ビジネス・ロジックとプレゼンテーションが1つのサーブレットに統合されています。このサーブレットをコンパイルすると、PhotoAlbumServlet.classおよびPhotoAlbumRequest.classの2つのクラス・ファイルが作成されます。
タスクの説明を理解するために、次の場所にあるPhotoAlbumServlet.javaファイルを参照してください。
<ORACLE_HOME>/ord/http/demo/servlet(LinuxおよびUNIXの場合)
<ORACLE_HOME>\ord\http\demo\servlet(Windowsの場合)
PhotoAlbumServletクラス
PhotoAlbumServletクラスは、次のタスクを実行します。
HttpServletを拡張し、ユーザーが入力した接続情報を含めます。
public class PhotoAlbumServlet extends HttpServlet
簡易接続プーリング・メカニズムの実装に使用されるJavaスタックをインスタンス化します。
private static Stack connStack = new Stack();
JDBC Thinドライバがロードされているかどうかを示すフラグを定義します。
private static boolean driverLoaded = false;
サーブレットの初期化メソッドを定義します。
public void init( ServletConfig config ) throws ServletException
{
super.init(config);
}
HttpServletRequestオブジェクトおよびHttpServletResponseオブジェクトを含むHTTP GETリクエストを処理するdoGet( )メソッドを定義し、PhotoAlbumRequestオブジェクトをインスタンス化してこのリクエストを処理し、原寸か縮小サイズのイメージをブラウザに配信するか、またはアップロード・フォームを表示したり、アルバムの内容を縮小イメージとして表示します。
public void doGet( HttpServletRequest request,
HttpServletResponse response )
throws ServletException, IOException
{
Connection conn = null;
//
// Use a try-block to ensure that JDBC connections are always returned
// to the pool.
//
try
{
//
// Get a JDBC connection from the pool.
//
conn = getConnection();
//
// Instantiate a PhotoAlbumRequest object to process the request.
//
PhotoAlbumRequest albumRequest =
new PhotoAlbumRequest( conn, request, response );
//
// Figure out what to do based on query string parameters.
//
String view_media = request.getParameter( "view_media" );
if ( view_media != null )
{
//
// Deliver a full-sized or thumbnail image to the browser.
//
albumRequest.viewMedia( view_media );
return;
}
else if ( request.getParameter( "view_form" ) != null )
{
//
// Display the HTML upload form.
//
albumRequest.viewUploadForm();
}
else if ( request.getParameter( "view_entry" ) != null )
{
//
// Display full-sized photo image.
//
albumRequest.viewPhoto();
}
else
{
//
// Display album contents with thumbnail images by default.
//
albumRequest.viewAlbum();
}
}
catch ( SQLException e )
{
//
// Log what went wrong.
//
e.printStackTrace( System.out );
//
// Turn SQL exceptions into ServletExceptions.
//
throw new ServletException( e.toString() );
}
finally
{
//
// If we have a JDBC connection, then return it to the pool.
//
freeConnection( conn );
}
}
アルバムへの新しい写真のアップロードに使用されるHTTP POSTリクエストを処理するdoPost( )メソッドを定義し、PhotoAlbumRequestオブジェクトをインスタンス化してこのリクエストを処理し、その後insertNewPhoto( )メソッドをコールします。
public void doPost( HttpServletRequest request,
HttpServletResponse response )
throws ServletException, IOException
{
Connection conn = null;
//
// Use a try-block to ensure that JDBC connections are always returned
// to the pool.
//
try
{
//
// Get a JDBC connection from the pool.
//
conn = getConnection();
// // Instantiate a PhotoAlbumRequest object to process the request.
//
PhotoAlbumRequest albumRequest =
new PhotoAlbumRequest( conn, request, response );
//
// Insert the photo into the album.
//
albumRequest.insertNewPhoto();
}
catch ( SQLException e )
{
//
// Log what went wrong.
// e.printStackTrace( System.out );
//
// Turn SQL exceptions into ServletExceptions.
//
throw new ServletException( e.toString() );
}
finally
{
//
// If we have a JDBC connection, then return it to the pool.
//
freeConnection( conn );
}
}
要約すると、PhotoAlbumServletクラスは、HTTP GETおよびHTTP POSTリクエストに応答して、接続プールからJDBC接続を割り当てます。複数のリクエストが同時に処理されるように、各HTTP GETまたはHTTP POSTリクエストには、接続プールから固有なJDBC接続が割り当てられます。HTTP GETリクエストはアルバムからのイメージ・データの取得に使用され、HTTP POSTリクエストはフォト・アルバムへのイメージ・データのアップロードに使用されます。その後、リクエストを実行するPhotoAlbumRequestクラスのインスタンスが作成され、リクエストを実行し、リクエスト完了時にJDBC接続を解放してプールに戻します。
JDBC接続の詳細は、『Oracle Database JDBC開発者ガイドおよびリファレンス』を参照してください。
PhotoAlbumRequestクラス
PhotoAlbumRequestクラスは、HTTP GETまたはHTTP POSTリクエストを実際に処理します。また、getPreferredFormat( )ファンクションおよび次のメソッドを定義します。
viewMedia( )およびinsertNewPhoto( )メソッドでは、3つのオブジェクトOrdHttpResponseHandler、OrdHttpUploadFormDataおよびOrdHttpUploadFileがインスタンス化されます。これらのオブジェクトは、それぞれOracle Multimedia Servlets and JSP Java APIのOrdHttpResponseHandler、OrdHttpUploadFormDataおよびOrdHttpUploadFileクラスのメソッドをコールするために使用されます。たとえば、viewMedia( )メソッドでは、次のコードに示すとおり、OrdHttpResponseHandlerオブジェクトがインスタンス化され、sendImage( )メソッドのコールに使用されます。
OrdHttpResponseHandler handler =
new OrdHttpResponseHandler( request, response );
handler.sendImage( img );
viewAlbum( )、viewPhoto( )、viewMedia( )およびinsertNewPhoto( )メソッドは、Oracleが提供するORAData(以前のgetCustomDatum)インタフェースおよびORADataFactory(以前のgetFactory)インタフェースを使用して、結果セットからのイメージまたは縮小イメージのORDImageオブジェクトの取得、高さと幅の情報の取得、ORDImage Javaオブジェクトからのイメージの取得およびブラウザへの配信、ORDImage Javaオブジェクトへのイメージのアップロードおよびphotos表内のイメージの更新を行います。例として、viewAlbum( )メソッドから引用したコード部分を次に示します。
OrdImage img =
(OrdImage)rset.getORAData( 4, OrdImage.getORADataFactory() );
.
.
.
out.print( "<td headers=\"image\"><a href=\"" + servletUri +
"?view_entry=yes&id=" + id + "\">" );
if ( img.getContentLength() > 0 )
{
if (img.getMimeType().startsWith("image/"))
{
out.print( "<img src=\"" + servletUri +
"?view_media=thumb&id=" + id + "\"" +
" height=" + img.getHeight() +
" width=" + img.getWidth() +
" alt=\"" + description + "\"" +
" border=1>" );
}
}
else
{
out.print( "[view image]" );
}
out.println( "</a></td>" );
out.println( "</tr>" );
各メソッドの詳細および実行する操作を次に示します。
viewAlbum( )メソッドは、次の操作を行います。
行数を0(ゼロ)に初期化します。
ファンクションprintPageHeader( )を使用して、HTMLページに共通ページ・ヘッダーを書き込みます。
SELECT文を実行して、フォト・アルバム内のすべての縮小イメージをフェッチし、説明を基準として順序付け、説明と位置の情報を縮小イメージ(存在する場合)とともに表示して、結果を結果セットとして戻します。
Description、LocationおよびImageという列を含むHTML表に縮小イメージを表示します。
whileブロック内で、結果セット内の最初の行のid値で始まるコンテンツを読み取ることによって結果セット内のコンテンツを読み取り、説明および位置の値を表示し、縮小イメージのORDImageオブジェクトを取得して各縮小イメージの高さ属性と幅属性を構成します。
HTMLアンカー・タグを使用する縮小イメージを表示します。このタグは、原寸イメージの表示に使用されます。ユーザーが縮小イメージまたは「view image」をクリックすると、原寸イメージが表示されます。
縮小イメージを表示するタグ<IMG SRC="<servlet-path>?view_media=thumb&id=...">を使用して、HTMLアンカー・タグ内にフォト・アルバムの内容を表示します。ここで、<servlet-path>はservletUriの値です。イメージ・フォーマットがOracle Multimediaでサポートされていないため縮小イメージが作成されていない場合、かわりにテキスト「view image」を表示します。
行数を増加させてアルバムが空かどうかを確認します。アルバムが空の場合、メッセージ「The photo album is empty」を表示します。
テキスト「Upload new photo」が指定されたprintLink( )ファンクションを使用して、HTMLページの下部近くにHTMLアンカー・タグを表示します。
printPageHeader( )ファンクションをコールして、HTMLページの下部に共通のトレーラを書き込みます。ただし、ここでは、ブール引数をFALSEに設定して共通ページ・トレーラを表示しないようにします。
結果セットをクローズして文を終了します。
viewPhoto( )メソッドは、写真の原寸イメージの表示および次の操作を行います。
ファンクションprintPageHeader( )を使用して、HTMLページに共通ページ・ヘッダーを書き込みます。
表示されているエントリのid列の値を取得します。
SQLのSELECT文を実行して、where句内のid値がパラメータ・マーカーであるエントリの説明、位置、および原寸イメージをフェッチし、結果を結果セットとして戻します。
後で<IMG SRC=...>イメージ・タグ内のイメージの高さと幅の属性を構成するために、結果セットからイメージのORDImageオブジェクトを取得します。
DescriptionおよびLocationという列名で始まるHTML表に原寸イメージを表示し、そのエントリの値を各列に表示します。
Photo列にイメージを表示するイメージ・タグ<IMG SRC="<servlet-path>?view_media=image&id=...">を使用して、このエントリの原寸イメージをフェッチするURLを作成します。ここで、<servlet-path>はservletUriの値です。
Oracle MultimediaのgetHeight( )およびgetWidth( )オブジェクト・メソッドをコールして、原寸イメージの高さと幅を表示します。イメージ・フォーマットがOracle Multimediaで認識されていない場合、高さと幅の値は0(ゼロ)となり、表示されません。
printPageHeader( )ファンクションをコールして、共通ページ・トレーラを表示するブール引数をTRUEに設定することで、HTMLページの下部に共通ページ・トレーラを書き込みます。
結果セットをクローズして文を終了します。
viewMedia( )メソッドは、縮小イメージと原寸イメージのどちらのURLからも起動され、photos表から縮小イメージまたは原寸イメージを取得し、OrdHttpResponseHandlerクラスを使用してそのイメージをブラウザに配信します。このメソッドは、次の操作を行います。
SQLのSELECT文を実行して、where句内のid値がパラメータ・マーカーである縮小イメージまたは原寸イメージをフェッチし、結果を結果セットとして戻します。このSQLのSELECT文は、文字列mediaに縮小イメージ列名または原寸イメージ列名を代入することによって動的に作成されます。
結果セットから行をフェッチします。
結果セットからORDImageオブジェクトを取得します。
OrdHttpResponseHandlerクラスを使用してOrdHttpResponseHandlerオブジェクトを作成し、ORDImageオブジェクトからイメージを取得して、sendImage( )メソッドを使用してブラウザに配信します。sendImage( )メソッドは、If-Modified-SinceヘッダーおよびLast-Modifiedヘッダーをサポートすることで、ブラウザ・コンテンツのキャッシュをサポートします。
結果セットをクローズして文を終了します。
viewUploadForm( )メソッドは、ユーザーが新しい写真をアップロードするために使用するHTMLフォームを表示し、次の操作を行います。
printPageHeader( )ファンクションをコールして、共通ページ・ヘッダーを生成します。
フォーム・アクションをmultipart/form-data POSTリクエストとして定義します。
アップロード・フォームのコンテンツを含むupload_form_fields静的文字列をコールします。アップロード・フォームは表として定義されています。この表には、DescriptionおよびLocationというラベルの行が含まれます。これらの行の入力タイプはtextで、それぞれ指定された説明および位置が含まれています。次の行File name:は、入力タイプはfileで、指定された写真が含まれています。最後の行にはラベルがなく、入力タイプはsubmitで、値Upload photoが含まれています。
printPageTrailer( )ファンクションをコールして、共通ページ・トレーラを生成します。
insertNewPhoto( )メソッド: 次の操作を行います。
OrdHttpUploadFormDataクラスを使用して、アップロードされた写真を含むmultipart/form-data POSTリクエストを解析します。
OrdHttpUploadFileクラスを使用して、新しい写真をデータベースにアップロードします。
SQLのSELECT photos_sequence.nextval文を実行し、photos表に挿入される新しい行用に、id列の次の値を取得します。
SQLのINSERT文を実行し、新しい行をphotos表に挿入します。
SQLのSELECT...FOR UPDATE文を実行し、初期化済の原寸イメージおよび縮小イメージのオブジェクトをphotos表からフェッチします。
OrdHttpUploadFileクラスのloadImage( )メソッドをコールして、imageというORDImageオブジェクトに原寸イメージを移入し、イメージのコンテンツに基づいて、そのイメージ・オブジェクトのプロパティまたは属性を設定します。
イメージ・フォーマットを確認し、ブラウザでインラインで表示されないイメージ・フォーマット(BMPイメージ・フォーマットなど)の場合は、getPreferredFormat( )メソッドをコールしてそのBMPイメージ・フォーマットを変換し、推奨イメージ・フォーマットを戻します。
OrdImageクラスのProcessCopy( )メソッドをコールして、原寸イメージを処理して縮小イメージを作成し、thumbというORDImageオブジェクトに移入します。
SQLのUPDATE文を実行し、データベース内の原寸イメージおよび縮小イメージを更新します。
写真のアップロードが成功したことを示すメッセージを表示し、ブラウザにページをリフレッシュするように指示します。
getPreferredFormat( )プライベート・ファンクションは、このサンプル・アプリケーションでは、BMPイメージ・フォーマットを変換し、イメージ内の色数に基づいて推奨イメージ・ファイル・フォーマットを戻します。色が存在しない場合はモノクロ・イメージ・フォーマット、色数が8を超える場合はJPEG、色数が1以上8未満の場合はGIFを戻します。
printPageHeader( )プライベート・ファンクションは、すべてのHTMLレスポンスに共通のHTMLヘッダーを表示します。
printPageTrailer( )プライベート・ファンクションは、すべてのHTMLレスポンスに共通のHTMLトレーラを表示します。
printMessage( )プライベート・ファンクションは、HTMLページ上にメッセージを出力します。
printHeading( )プライベート・ファンクションは、HTMLページ上にヘッダーを出力します。
printLink( )ファンクションは、標準形式のHTMLアンカー・タグを作成します。
Oracle Multimedia JSPフォト・アルバム・サンプル・アプリケーションは、Oracle Multimedia Servlets and JSP Java APIを使用して、マルチメディア・データをデータベースにアップロードおよびデータベースから取得する方法を示すJavaServer Pages(JSP)アプリケーションです。ユーザーは、アプリケーションを構成するJSPファイルにアクセスして、各写真の縮小イメージを含むアルバムの内容の表示、任意の写真の原寸イメージの表示、およびフォト・アルバムへの新しい写真のアップロードを行います。
このフォト・アルバム・アプリケーションでは、Oracle Multimedia Imageオブジェクト型を使用して、Oracle Databaseに格納されたメディア・データをアップロードおよび取得する方法を示します。
このフォト・アルバム・アプリケーションをインストールすると、photosという名前の表およびphotos_sequenceという名前の順序が作成されます。
photos表は、CREATE TABLE文で次のとおり作成されています。
CREATE TABLE photos( id NUMBER PRIMARY KEY,
description VARCHAR2(40) NOT NULL,
location VARCHAR2(40),
image ORDSYS.ORDIMAGE,
thumb ORDSYS.ORDIMAGE )
--
-- store full-size images and thumbnail images as SecureFile LOBs
--
LOB(image.source.localdata) STORE AS SECUREFILE
LOB(thumb.source.localdata) STORE AS SECUREFILE;
image列およびthumb列のデータ型が、それぞれ原寸イメージおよび生成される縮小イメージを格納するOracle Multimedia Imageオブジェクト型として定義されていることに注意してください。
photos_sequence順序は、CREATE SEQUENCE文で次のとおり作成されています。
CREATE SEQUENCE photos_sequence;
サンプル・アプリケーション・ファイルおよびREADME.txtファイルは次のディレクトリにあります。
<ORACLE_HOME>/ord/http/demo/jsp(LinuxおよびUNIXの場合)
<ORACLE_HOME>\ord\http\demo\jsp(Windowsの場合)
次の項では、JSPフォト・アルバム・アプリケーションの実行方法について説明します。このサンプル・アプリケーションをインストールおよび使用する場合の追加要件および手順については、README.txtファイルを参照してください。
セットアップ・タスクを完了してJSPフォト・アルバム・アプリケーションを構築したら、Webブラウザのアドレス・フィールドに次のURLを入力してこのフォト・アルバム・アプリケーションを実行できます。
Oracle Application ServerまたはOracle Databaseをデフォルト設定でインストールしている場合
<protocol><hostname:port-number>/demo/PhotoAlbum.jsp
WindowsにTomcat 3.2をデフォルト設定でインストールしている場合
<protocol><hostname:port-number>/examples/jsp/PhotoAlbum.jsp
<protocol>フィールドにはhttp://を入力し、<hostname:port-number>フィールドにはHTTPサーバーを実行しているシステムのホスト名とポート番号を入力します。
このフォト・アルバム・アプリケーションを初めて起動した際、その時点でアルバムに格納されているすべてのイメージが表示されます。アプリケーションを初めてインストールした直後は、デフォルトで、フォト・アルバムには何も入っていません。新しい写真をアップロードするには、「Upload new photo」をクリックします。写真の説明と撮影場所を入力し、イメージ・ファイルの名前を入力するか、またはディレクトリ内のイメージ・ファイルの位置を参照して、「Upload photo」をクリックします。新しい写真が追加されたフォト・アルバムの内容が表示されます。縮小イメージをクリックすると、写真が原寸で表示されます。
このフォト・アルバム・アプリケーションに縮小イメージではなくテキスト「view image」が表示される場合、アップロードされたイメージのフォーマットがOracle Multimediaで認識されていません。「view image」をクリックすると、原寸イメージが表示されます。
前述の手順に従って、フォト・アルバム・アプリケーションに自由に写真をロードできます。
JSPフォト・アルバム・アプリケーションでは、5つのJSPファイルがそれぞれアクセスするメソッドをJavaBeanに含めることで、プレゼンテーションからビジネス・ロジックが分離されています。このアプリケーションをコンパイルすると、PhotoAlbumBean.classファイルが作成されます。このファイルには、ユーザーが入力する接続情報が含まれます。また、このファイルは、getId( )、getDescription( )、getLocation( )およびgetPreferredFormat( )ファンクションと次のメソッドを定義します。
タスクの説明を理解するために、次の場所にあるJSPファイルを参照してください。
<ORACLE_HOME>/ord/http/demo/jsp(LinuxおよびUNIXの場合)
<ORACLE_HOME>\ord\http\demo\jsp(Windowsの場合)
PhotoAlbumEntryViewer、PhotoAlbumMediaViewer、PhotoAlbumおよびPhotoAlbumInsertPhoto JSPファイルでは、jsp:useBeanアクション・タグを使用して、ID、PhotoAlbumBeanクラスとの関連付け、およびOracle Multimedia Servlets and JSP Java APIのOrdHttpJspResponseHandlerおよびOrdHttpUploadFormDataクラスとの関連付けが定義されています。例として、PhotoAlbumInsertPhoto JSPファイルに含まれているコードを次に示します。
<jsp:useBean id="album" scope="page" class="PhotoAlbumBean"/>
<jsp:useBean id="handler" scope="page"
class="oracle.ord.im.OrdHttpJspResponseHandler"/>
<jsp:useBean id="formData" scope="page" class="oracle.ord.im.OrdHttpUploadFormData"/>
このjsp:useBeanアクション・タグを使用することで、これらのオブジェクトを対応するID値(album、handlerおよびformData)で参照し、それらのクラスのメソッドをコールできます。
Oracle Multimedia Servlets and JSP Java APIのOrdHttpUploadFileクラスは、PhotoAlbumBean.javaファイル内のinsertNewPhoto( )メソッドで、uploadPhotoという名前のオブジェクトとして定義されます。このオブジェクトを使用して同じクラスのloadImage( )メソッドがコールされ、写真がphotos表にロードされます。この操作を示すコード部分を次に示します。
public void insertNewPhoto( OrdHttpUploadFile uploadPhoto )
throws SQLException, ServletException, IOException
.
.
.
uploadPhoto.loadImage( image );
.
.
.
PhotoAlbumBean.javaファイルに定義されているinsertNewPhoto( )メソッドは、Oracleが提供するORAData(以前のgetCustomDatum)インタフェースおよびORADataFactory(以前のgetFactory)インタフェースを使用して、イメージおよび縮小イメージをORDImage Javaオブジェクトにアップロードします。このメソッドは、まずSQLのSELECT...FOR UPDATE文を実行してphotos表内の更新対象の行を選択し、次にSQLのUPDATE文を実行して更新対象の行のimage列およびthumb列を更新します。この操作を示すコード部分を次に示します。
stmt = (OraclePreparedStatement)conn.prepareStatement(
"select image,thumb from photos where id = ? for update" );
stmt.setString( 1, id );
rset = (OracleResultSet)stmt.executeQuery();
if ( !rset.next() )
{
throw new ServletException( "new row not found in table" );
}
image = (OrdImage)rset.getORAData( 1, OrdImage.getORADataFactory());
thumb = (OrdImage)rset.getORAData( 2, OrdImage.getORADataFactory());
rset.close();
stmt.close();
.
.
.
//
// Prepare and execute a SQL statement to update the full-sized and
// thumbnail images in the database.
//
stmt = (OraclePreparedStatement)conn.prepareStatement(
"update photos set image = ?, thumb = ? where id = ?" );
stmt.setORAData( 1, image );
stmt.setORAData( 2, thumb );
stmt.setString( 3, id );
stmt.execute();
stmt.close();
//
// Commit the changes.
//
conn.commit();
}
PhotoAlbumBean.javaファイル(PhotoAlbumBean JavaBean)に定義されているfetch( )メソッドは、ORADataインタフェースおよびORADataFactoryインタフェースを使用して結果セットから次の行をフェッチし、ORDImage Javaオブジェクトからイメージおよび縮小イメージを取得して、各イメージをブラウザに配信します。次の例にこのコードを示します。
public boolean fetch()
throws SQLException
{
if ( rset.next() )
{
id = rset.getString( 1 );
description = rset.getString( 2 );
location = rset.getString( 3 );
image = (OrdImage)rset.getORAData( 4, OrdImage.getORADataFactory() );
thumb = (OrdImage)rset.getORAData( 5, OrdImage.getORADataFactory() );
return true;
}
else
{
rset.close();
stmt.close();
return false;
}
}
各JSPファイルの詳細を次に示します。
PhotoAlbum.jsp
このJSPファイルは、JSPフォト・アルバム・アプリケーションへのエントリ・ポイントです。このファイルは次の操作を行います。
PhotoAlbumBean JavaBeanを使用して、photos表のコンテンツにアクセスします。
OrdHttpJspResponseHandlerクラスを使用して、photos表からのイメージ・データの取得、およびJavaサーブレットからブラウザまたはその他のHTTPクライアントへのイメージ・データの配信を容易にします。
ページ・タイトルを、HTMLヘッダーおよび共通ページ・ヘッダーに表示します。
Description、LocationおよびImageという列を含む表に縮小イメージを表示します。
try/catchブロックを使用して、JDBC接続が確実に解放されるようにします。
selectTable( )メソッドをコールして、photos表内のすべての行を選択します。
行数を0(ゼロ)に初期化します。
getDescription( )メソッドとgetLocation( )メソッドを順番にコールし、それらの値を適切な列に出力することによって、フォト・アルバム内のエントリを表示します。位置情報が空白の場合、Location列内に空白を出力します。
フォト・アルバムの内容を、HTMLアンカー・タグを使用した縮小イメージとして表示します。このアンカー・タグでは、getID( )ファンクションをコールしてID値を取得するPhotoAlbumEntryViewer.jspファイルがコールされます。
getThumb( )メソッドをコールして縮小イメージを取得し、getContentLength( )メソッドをコールしてそのイメージの長さを判断します。
イメージの長さとして戻された値が0(ゼロ)より大きいかどうかをテストします。長さが0より大きい場合は、<IMG SRC="PhotoAlbumMediaViewer.jsp?media=thumb&...>という形式のイメージ・タグを使用して縮小イメージを表示します。そうでない場合は、リンク「view image」をImageというラベルの付いた列に表示します。このリンクをクリックすると、原寸イメージが取得されます。
フォト・アルバムが空の場合、メッセージ「The photo album is empty」を表示します。フォト・アルバムが空でない場合、メッセージ「Select the thumbnail to view the full-sized image」を表示します。
try/catchブロックを終了し、finally句でrelease( )メソッドをコールしてJDBC接続を解放します。
ページの下部に、アップロード・フォームへのテキスト・リンク「Upload new photo」を表示します。このリンクでは、PhotoAlbumUploadForm.jspファイルがコールされます。
PhotoAlbumEntryViewer.jsp
このJSPファイルは、PhotoAlbum.jspファイルによってコールされ、アルバム内の写真の原寸イメージを1つ表示します。このJSPファイルは、次の操作を行います。
PhotoAlbumBean JavaBeanを使用して、photos表のコンテンツにアクセスします。
OrdHttpJspResponseHandlerクラスを使用して、photos表からのイメージ・データの取得、およびJavaサーブレットからブラウザまたはその他のHTTPクライアントへのイメージ・データの配信を容易にします。
ページ・タイトルを、HTMLヘッダーおよび共通ページ・ヘッダーに表示します。
getParameter( )メソッドをコールしてid値を取得する、idという文字列を定義します。
id文字列の値がNULLである場合、メッセージ「Malformed URL, no id parameter」を表示します。
try/catchブロックを使用して、JDBC接続が確実に解放されるようにします。
idの値を指定したselectRowById( )メソッドをコールし、表示するエントリを選択します。このid値に基づいてフェッチする次の行が見つからない場合、メッセージ「Entry not found: <id value>」を表示します。
getDescription( )メソッドをコールしてその値をDescriptionヘッダーの下に表示し、getLocation( )メソッドをコールしてその値をLocationヘッダーの下に表示することで、アルバム内にエントリを表示します。
Photoヘッダーの下に<IMG SRC="PhotoAlbumMediaViewer.jsp?media=image&...">という形式のイメージ・タグを使用して、アルバム内の写真を原寸で1つ表示します。
getHeight( )およびgetWidth( )メソッドをコールして、原寸イメージの高さと幅を表示します。イメージ・フォーマットがOracle Multimediaで認識されていない場合、高さと幅の値は0(ゼロ)となり、表示されません。
ページの下部に、「Return to photo album」というリンクを表示します。このリンクでは、PhotoAlbum.jspファイルがコールされます。
try/catchブロックを終了し、finally句でrelease( )メソッドをコールしてJDBC接続を解放します。
PhotoAlbumMediaViewer.jsp
このJSPファイルは、PhotoAlbum.jspおよびPhotoAlbumEntryViewer.jspファイルによってコールされます。このファイルは、PhotoAlbumBean JavaBeanを使用してphotos表から1つの縮小イメージまたは原寸イメージを取得し、OrdHttpResponseHandlerクラスを使用してそのイメージをブラウザに配信します。このJSPファイルは、次の操作を行います。
PhotoAlbumBean JavaBeanを使用して、photos表のコンテンツにアクセスします。
OrdHttpJspResponseHandlerクラスを使用して、photos表からのイメージ・データの取得、およびJavaサーブレットからブラウザまたはその他のHTTPクライアントへのイメージ・データの配信を容易にします。
getParameter( )メソッドをコールしてid値を取得する、idという文字列を定義します。
getParameter( )メソッドをコールしてmedia値を取得する、mediaという文字列を定義します。
文字列idおよびmediaの値がNULLでないかぎり適用される条件を設定します。
try/catchブロックを使用して、JDBC接続が確実に解放されるようにします。
selectRowById( )メソッドをコールして、idの値が一致する行をphotos表から選択します。
原寸イメージまたは縮小イメージを配信します。これには、まずOrdHttpJspResponseHandlerクラスのsetPageContext( )メソッドをコールしてページ・コンテキスト・オブジェクトを指定し、次に、getImage( )メソッドをコールしてイメージをORDImageオブジェクトに戻します。その後、OrdHttpResponseHandlerクラスのsendImage( )メソッドをコールしてORDImageオブジェクトからイメージを取得し、そのイメージをブラウザに配信します。メディアの値がimageの場合はイメージが、thumbの場合は縮小イメージがブラウザに配信されます。sendImage( )メソッドは、If-Modified-SinceヘッダーおよびLast-Modifiedヘッダーをサポートすることで、ブラウザ・コンテンツのキャッシュをサポートします。
try/catchブロックを終了し、finally句でrelease( )メソッドをコールしてJDBC接続を解放します。
リクエストを認識できない場合、メッセージ「PhotoAlbumMediaViewer.jsp - malformed URL」を表示します。
PhotoAlbumUploadForm.jsp
このJSPファイルは、PhotoAlbum.jspファイルによってコールされ、ユーザーがアルバムに新しい写真をアップロードするために使用するHTMLフォームを表示します。このJSPファイルは、次の操作を行います。
ページ・タイトルを、HTMLヘッダーおよび共通ページ・ヘッダーに表示します。
文字列の値がNULLかどうかを判断するために、引数errorを指定したgetParameter( )メソッドをコールして、前回のイメージのアップロードからのエラー・メッセージを「Error message」列に表示します。
テキスト「Upload new photo」を含むヘッダーを表示します。
PhotoAlbumInsertPhoto.jspファイルがアップロード・リクエストをmultipart/form-data POSTリクエストとして処理するように指定するフォーム・アクションを定義します。
Description、LocationおよびFile name:という行を含むアップロード・フォームを表示します。
表として定義されたアップロード・フォームのコンテンツを表示します。この表には、DescriptionおよびLocationというラベルの行が含まれます。これらの行の入力タイプはtextで、それぞれ指定された説明および位置が含まれています。次の行File name:は、入力タイプはfileで、指定された写真が含まれています。最後の行にはラベルがなく、入力タイプはsubmitで、値Upload photoが含まれています。
ページの下部に、「Return to photo album」というリンクを表示します。このリンクでは、PhotoAlbum.jspファイルがコールされます。
PhotoAlbumInsertPhoto.jsp
このJSPファイルは、PhotoAlbumUploadForm.jspファイルによってコールされ、OrdHttpUploadFormDataクラスを使用して、アップロードされた写真を含むPOSTリクエスト内のPOSTデータを解析します。このJSPファイルは、次の操作を行います。
PhotoAlbumBean JavaBeanを使用して、photos表のコンテンツにアクセスします。
OrdHttpJspResponseHandlerクラスを使用して、photos表からのイメージ・データの取得、およびJSPファイルからブラウザまたはその他のHTTPクライアントへのイメージ・データの配信を容易にします。
OrdHttpUploadFormDataクラスを使用して、multipart/form-dataエンコーディングを含むPOSTデータを解析し、通常のフォームのフィールドやアップロード・ファイルをJSPファイルにアクセス可能にすることによって、POSTリクエストの処理を容易にします。
文字列descriptionおよびlocationの値をnullに設定し、OrdHttpUploadFileオブジェクトのuploadPhotoをnullに設定します。
try/catchブロックを使用して、JDBC接続が確実に解放されるようにします。
OrdHttpUploadFileオブジェクトをPhotoAlbumBeanクラスに渡し、写真をデータベースに格納します。
OrdHttpUploadFormDataクラスのsetServletRequest( )メソッドをコールし、リクエストするServletRequestオブジェクトを指定します。
OrdHttpUploadFormDataクラスのisUploadRequest( )メソッドをコールして、リクエストがmultipart/form-dataエンコーディングを使用してエンコードされているかどうかをテストします。
isUploadRequest( )メソッドへのコールによって、FALSE以外のブール式が戻された場合、リクエストをPhotoAlbumUploadForm.jspファイルに転送します。
OrdHttpUploadFormDataクラスのparseFormData( )メソッドをコールして、フォーム・データを解析します。
OrdHttpUploadFormDataクラスのgetParameter( )メソッドをコールして、説明と位置のフィールドの値を取得します。また、同じクラスのgetFileParameter( )メソッドをコールして、アップロードするファイルの名前を取得します。
OrdHttpUploadFormDataクラスのgetFileParameter( )メソッドをコールして、ファイル名がNULLでないことをテストして確認し、OrdHttpUploadFileクラスのgetOriginalFileName( )メソッドをコールして、ブラウザによって提供された元のファイル名がNULLでないことを確認するか、またはOrdHttpUploadFileクラスのgetContentLength( )メソッドをコールして、ファイルのコンテンツ長が空であることを確認します。
有効なイメージ・ファイルが存在する場合、リクエストをPhotoAlbumUploadForm.jspファイルに転送します。
説明がNULLまたは空である場合、OrdHttpUploadFileクラスのgetSimpleFileName( )メソッドをコールして、ファイル名を説明として使用します。
PhotoAlbumBean.java JavaBeanのsetDescription( )、setLocation( )およびinsertNewPhoto( )メソッドをコールして、photos表に新しいエントリを挿入します。
try/catchブロックを終了し、finally句で、release( )メソッドをコールしてJDBC接続を解放します。また、OrdHttpUploadFormDataオブジェクトのrelease( )メソッドをコールして、そのオブジェクトが保持していたすべてのリソースを解放します。
更新されたフォト・アルバムを表示します。HTMLヘッダーおよび共通ページ・ヘッダーにページのタイトルを表示し、 PhotoAlbum.jspファイルをコールしてブラウザにメイン・ページを表示し、ヘッダー「Photo successfully uploaded into photo album」およびメッセージ「Please click on link below or wait for the browser to refresh the page」を表示します。
メイン・ページの下部に、「Return to photo album」というリンクを表示します。このリンクでは、PhotoAlbum.jspファイルがコールされます。
PhotoAlbumBean.java
これは、JSPファイルがデータベースにアクセスするために使用するJavaBeanです。
このJavaBeanは、任意のリクエストのための最初のコールを受信すると、接続プールからJDBC接続を割り当てます。同じリクエストの後続のコールには、同じ接続が再利用されます。各リクエストの完了時に、各JSPファイルがJavaBeanをコールし、JDBC接続をプールに戻します。複数のリクエストが同時に処理されるように、各HTTP GETまたはHTTP POSTリクエストには、接続プールから固有なJDBC接続が割り当てられます。
次のメソッドが定義されています。
selectTable( )メソッド: photos表内のすべての行を選択し、位置を基準として順序付けし、結果を結果セットに戻します。
selectRowById( )メソッド: where句内のid値がパラメータ・マーカーである特定の行をphotos表から選択し、結果を結果セットに戻します。
fetch( )メソッド: 結果セットから次の行をフェッチします。
insertNewPhoto( )メソッド: 次の操作を行います。
OrdHttpUploadFileクラスを使用して、新しい写真をデータベースにアップロードします。
引数をFALSEに設定したsetAutoCommit( )メソッドをコールして、自動コミットを無効にします。
SQLのSELECT photos_sequence.nextval文を実行し、photos表に挿入される新しい行用に、id列の次の値を取得します。
SQLのINSERT文を実行し、新しい行をphotos表に挿入します。
SQLのSELECT...FOR UPDATE文を実行し、初期化済の原寸イメージおよび縮小イメージのオブジェクトをphotos表からフェッチします。
OrdHttpUploadFileクラスのloadImage( )メソッドをコールしてイメージをロードし、imageというORDImageオブジェクトに原寸イメージを移入し、イメージのコンテンツに基づいて、そのイメージ・オブジェクトのプロパティまたは属性を設定します。
getContentFormat( )メソッドをコールしてイメージ・ファイル・フォーマットを取得し、これがNULLではなく、MIMEタイプがBMPである場合は、process( )メソッドをコールしてイメージの処理を試行し、getPreferredFormat( )メソッドをコールして、イメージ内の色数に基づいてモノクロ、GIFまたはJPEGイメージ・フォーマットへの変換を試行します。
OrdImageクラスのprocessCopy( )メソッドをコールして、原寸イメージをコピーし、そのコピーを処理して縮小イメージを作成し、thumbというORDImageオブジェクトに移入します。
SQLのUPDATE文を実行し、データベース内の原寸イメージおよび縮小イメージを更新します。
変更をコミットします。
release( )メソッド: 結果セットおよび文オブジェクトを解放し、JDBC接続を空きリストまたはスタックに戻します。
getメソッド(getId( )、getDescription( )、getLocation( )、getImage( )およびgetThumb( ))およびsetメソッド(setId( )、setDescription( )およびsetLocation( )): すべての属性または列の属性の取得または設定に使用されます。
getConnection( )プライベート・ファンクション: 単純なJDBC接続プールを実装します。
freeConnection( )プライベート・ファンクション: リクエスト完了時にJDBC接続を解放してプールに戻します。
getPreferredFormat( )プライベート・ファンクション: BMPイメージの色のビット数に基づいて推奨イメージ・ファイル・フォーマットを戻します。色のビットが存在しない場合はモノクロ・イメージ、色が8ビットを超える場合はJPEG、色が1〜8ビットの場合はGIFを戻します。
Oracle Multimedia ASP/VBScriptフォト・アルバム・サンプル・アプリケーションは、Oracle Multimedia ORDImage型およびOracle Objects for OLEを使用して、格納されたマルチメディア・データをアップロード、取得および処理する方法を示すASP/VBScriptアプリケーションです。ユーザーは、アプリケーションにアクセスして、各写真の縮小イメージを含むアルバムの内容の表示、任意の写真の原寸イメージの表示、およびフォト・アルバムへの新しい写真のアップロードを行います。
このフォト・アルバム・アプリケーションでは、Oracle Multimedia Imageオブジェクト型を使用して、Oracle Databaseに格納されたメディア・データをアップロードおよび取得する方法を示します。
このフォト・アルバム・アプリケーションをインストールすると、photosという名前の表およびphotos_sequenceという名前の順序が作成されます。
photos表は、CREATE TABLE文で次のとおり作成されています。
CREATE TABLE photos( id NUMBER PRIMARY KEY,
description VARCHAR2(40) NOT NULL,
location VARCHAR2(40),
image ORDSYS.ORDIMAGE,
thumb ORDSYS.ORDIMAGE )
--
-- store full-size images and thumbnail images as SecureFile LOBs
--
LOB(image.source.localdata) STORE AS SECUREFILE
LOB(thumb.source.localdata) STORE AS SECUREFILE;
image列およびthumb列のデータ型が、それぞれ原寸イメージおよび生成される縮小イメージを格納するOracle Multimedia Imageオブジェクト型として定義されていることに注意してください。
photos_sequence順序は、CREATE SEQUENCE文で次のとおり作成されています。
CREATE SEQUENCE photos_sequence;
サンプル・アプリケーション・ファイルおよびREADME.txtファイルは次のディレクトリにあります。
<ORACLE_HOME>/ord/http/demo/asp(LinuxおよびUNIXの場合)
<ORACLE_HOME>\ord\http\demo\asp(Windowsの場合)
次の項では、ASP/VBScriptフォト・アルバム・アプリケーションの実行方法について説明します。このサンプル・アプリケーションをインストールおよび使用する場合の追加要件および手順については、README.txtファイルを参照してください。
Microsoft IISでASP/VBScriptフォト・アルバム・アプリケーションをインストールおよび設定し、アプリケーションの接続パラメータを設定したら、このアプリケーションを実行できます。
このアプリケーションを使用するには、Webブラウザのアドレス・バーにフォト・アルバムのURLを入力します。次に例を示します。
http://<hostname:port>/photoAlbum
アプリケーションを初めて起動した際、その時点でアルバムに格納されているすべてのイメージが表示されます。アプリケーションを初めてインストールした直後は、デフォルトで、フォト・アルバムには何も入っていません。新しい写真をアップロードするには、「Upload new photo」をクリックします。写真の説明と撮影場所を入力し、イメージ・ファイルの名前を入力するか、またはディレクトリ内のイメージ・ファイルの位置を参照して、「Upload new photo」をクリックします。新しい写真が追加されたフォト・アルバムの内容が表示されます。縮小イメージをクリックすると、写真が原寸で表示されます。
このフォト・アルバム・アプリケーションに縮小イメージではなくテキスト「view image」が表示される場合、アップロードされたイメージのフォーマットがOracle Multimediaで認識されていません。「view image」をクリックすると、原寸イメージが表示されます。
前述の手順に従って、フォト・アルバム・アプリケーションに自由に写真をロードできます。
ASP/VBScriptフォト・アルバム・アプリケーションを実装する最上位ファイルは、viewAlbum.asp、viewEntry.aspおよびuploadPhoto.aspです。また、getPhoto.aspファイルによってデータベースからイメージが取得され、insertPhoto.aspファイルによって新しいイメージがデータベースに挿入されます。
viewAlbum.asp
viewAlbumページは、フォト・アルバムの内容を、Description、LocationおよびImageという列を含む表形式で表示します。
縮小イメージは、SQLのSELECT文の説明を基準として順序付けされ、原寸イメージを表示するアンカー・タグ<img src="getPhoto.asp?entry_id=...">を使用して表示されます。このコード部分を次に示します。
<A href="viewEntry.asp?entry_id=<%=strId%>">
<% If objThumb.contentlength > 0 Then %>
<IMG border = 1
height="<%=objThumb.height%>"
width="<%=objThumb.width%>"
alt="<%=strDescription%>"
src="getPhoto.asp?media=thumb&entry_id=<%=strId%>"
>
Oracle Multimediaでサポートされないイメージ・フォーマットの場合、縮小イメージは作成されず、データベースにも格納されません。この場合、縮小イメージのかわりに「view image」というテキストが、表のImage列に表示されます。
ページには、「Select the thumbnail to view the full-size image」というテキストが表示されます。ページの下部に表示される「Upload new photo」リンクがクリックされると、uploadPhoto.aspファイルがコールされます。このファイルによって、新しい写真をデータベースにアップロードするために使用できるアップロード・フォーム(uploadForm.inc)が表示されます。
viewEntry.asp
viewEntryページは、写真の原寸イメージを表示します。このページも、<img src="getPhoto.asp?entry_id...">タグを使用してイメージを表示します。
<TD vAlign=top scope="col"><B>Photo:</B></TD>
<TD scope="col">
<IMG border=1
alt="<%=strDescription%>"
src="getPhoto.asp?media=image&entry_id=<%=strId%>"
<% If objImage.height > 0 And objImage.width > 0 Then %>
height="<%=objImage.height%>"
width="<%=objImage.width%>"
<% End If %>
>
</TD>
いずれのURLでも、Oracle Objects for OLEを使用したデータベースとの通信を介してデータベースからイメージが取得され、そのイメージがブラウザに配信されます。
ページの下部に表示される「Return to photo album」リンクがクリックされると、viewAlbum.aspファイルがコールされます。このファイルによって、フォト・アルバム表および表示する一連の縮小イメージが提供されます。
uploadPhoto.asp
uploadPhotoページは、ユーザーがデータベースに新しい写真をアップロードするためのHTMLフォーム(uploadForm.inc)を表示します。ユーザーは、このフォームに新しい写真の説明と位置の情報、およびイメージ・ファイル名を入力します。このフォームは、insertPhotoページを起動します。このコードを次に示します。
<FORM action="insertPhoto.asp" method="post" encType="multipart/form-data">
insertPhoto.asp
insertPhotoページは、イメージをphotos表にロードし、そのイメージの縮小イメージを自動的に生成します。
uploadPhotoページの下部近くにある「Upload photo」をクリックすると、入力タイプがsubmitであるフォーム・アクションが実行されます。このコードを次に示します。
<TD colSpan=2><INPUT type=submit value="Upload photo"></TD>
getPhoto.asp
getPhotoページは、イメージのphoto列にあるインジケータ値(thumbまたはimage)に基づいて、データベースから縮小イメージまたは原寸イメージを取得し、そのイメージをブラウザに配信します。リクエストされたイメージがブラウザのキャッシュ内に存在し、そのキャッシュが有効である場合、このページはキャッシュからそのイメージを取得します。そうでない場合は、イメージのMIMEタイプをデータベース内のイメージ属性値に基づいて設定し、データベースからそのイメージを取得して、ブラウザに配信します。この操作を実行する文を次に示します。
If CacheIsValid( setPhotos(1).value ) Then Response.Status = HTTP_STATUS_NOT_MODIFIED Else ' Set the mime type header and deliver the image to the browser. SetLastModified( setPhotos(1).value ) Response.ContentType = objMedia.mimetype ReadBlob objMedia.source.localData End If