セクション 4: BLOB 内の JPEG の先頭を見つける
OLE オブジェクト型の形式 - 3 つだけ!
あとは、イメージをディスクに (プレーンなバイナリ ファイルとして) 保存し、その中に何が入っているかを理解するだけです。
すべての画像ファイル (形式) には、画像を一意に識別するファイル ヘッダーがあります。 JPG 画像ファイルは、いわゆる SOI タグで始まり、その 16 進値は $FFD8 です。
次のコード行は、画像フィールドの値を作業ディレクトリ内の関連ファイル (BlobImage.dat) に保存します。このコードをフォームの OnCreate イベントに配置し、プロジェクトの開始後に削除します。
ADOTable1Picture.SaveToFile('BlobImage.dat');
このファイルを入手したら。 16 進エディタを使用してその内容を表示できます。
信じますか? MS Access は、接続された OLE オブジェクトへのパスをオブジェクト定義の一部として OLE オブジェクト フィールドに保存します。 OLE オブジェクトのストレージ定義は文書化されていないため (!? これは MS から直接提供されています)、実際の画像データが書き込まれる前にそれを知る方法はありません。
この質問を 2 つの部分に分けて考えてみましょう。まず、「FFD8」を見つけて、そこからイメージの読み取りを開始する必要があります。 2 番目: 「FFD8」は、ファイル内の同じ位置に常にあるとは限りません。結論: Access データベースに OLE オブジェクトとして保存されている JPG ファイルの SOI タグの場所を返す関数が必要です。
正しい方法は 4 つです。
Blob タイプ フィールドが提供されている場合、この関数は ADOBlobStream 内の「FFD8」文字列の位置を返す必要があります。 ReadBuffer はストリームからバイトごとにデータを読み取ります。 ReadBuffer を呼び出すたびに、ストリームの位置がバイトごとに移動します。この関数は、2 バイトが SOI マーカーにつながる場合のストリームの位置を返します。これが関数です:
関数 JpegStartsInBlob(PicField:TBlobField):integer;
変数
bS : TADOBlobStream;
バッファ: ワード;
hx: 文字列;
始める
結果 := -1;
bS := TADOBlobStream.Create(PicField, bmRead);
試す
while (Result = -1) および (bS.Position + 1 < bS.Size)
始める
bS.ReadBuffer(バッファ, 1);
hx:=IntToHex(バッファ, 2);
hx = 'FF' の場合は開始します
bS.ReadBuffer(バッファ, 1);
hx:=IntToHex(バッファ, 2);
hx = 'D8' の場合、結果 := bS.Position - 2
それ以外の場合、hx = 'FF' の場合
bS.位置 := bS.位置-1;
終了; //場合
// 終了;
ついに
bS.フリー
終了; //試してください
終わり;
SOI マーカーの位置を取得したら、それを使用して ADOBlob ストリーム内の画像の位置を見つけることができます。
JPEGを使用します。
...
手順 TForm1.btnShowImageClick(送信者: TObject);
変数
bS : TADOBlobStream;
写真: TJpegImage;
始める
bS := TADOBlobStream.Create(AdoTable1Picture, bmRead);
試す
bS.Seek(JpegStartsInBlob(AdoTable1Picture),soFromBeginning);
Pic:=TJpegImage.Create;
試す
Pic.LoadFromStream(bS);
ADOImage.Picture.Graphic:=Pic;
ついに
写真無料。
終わり;
ついに
bS.フリー
終わり;
終わり;
プロジェクトを実行します。OK!
さて、プログラミングが楽しくないと誰が言えるでしょうか?
注: 実際のコード プログラムでは、TDataSet の AfterScroll イベント (ADOTable1AfterScroll イベント プロシージャ内にあります) の現在の行から画像を読み取って表示するコードを追加します。 AfterScroll イベントは、アプリケーションがあるレコードから別のレコードにスクロールするときに発生します。
アイデアその5!
それがこの章の内容です。これで、興味のあるすべての JPG 画像を保存して表示できるようになります。この記事の最後のページでは、完全なコード (form1 ユニット) を提供します。すべてのデータ配置はフォームの OnCreate イベントに配置されます。これにより、3 つのコンポーネントすべてが正しく接続されるようになり、設計時にオブジェクト インスペクターを使用する必要がなくなります。
この章が初心者向けではないことは認めますが、世界は残酷な場所です。もう 1 つ、結局のところ、テーブルに写真を変更する (または新しい写真を追加する) 方法さえわからないことに気づきました。はい、それは全く別の話です!