当前位置:编程学习 > Delphi >>

Delphi数据库编程教程(六)

 第四节  在BLOB中寻找JPEG的开端

      OLE对象类型格式—思路三(OLE object type format - take three!)
      现在所有我们需要做的是存储图片到磁盘(存为普通的二进制文件)并了解它里门的内容是什么。

      所有的图片文件(格式)都有用来唯一的标识图像的文件头。JPG图片文件以所谓的SOI标记开始,该标记的十六进制值是$FFD8。

下面一行代码存储图片字段值到工作目录的相关文件(BlobImage.dat)。在表单的OnCreate事件中放置这条代码,开始工程以后再移除该代码。

      ADOTable1Picture.SaveToFile(BlobImage.dat);

      一旦我们有了这个文件。我们就可以使用Hex editor看它的内容。

Jpeg as OLE object binary file

      你相信吗?MS Access把连接的OLE对象的路径作为对象定义的一部分存储在OLE对象字段中。因为OLE对象的存储定义没有被文档化(!?这直接来自于MS),所以没有办法知道真正的图像数据被写之前能得到什么。

      分两个部分考虑这个问题。第一:我们需要找到FFD8并从那儿开始读取图像。第二:FFD8不可能总在文件的同一个位置。结论:我们需要一个函数,返回Access数据库中存储为OLE对象的JPG文件的SOI标记的位置。

      正确的方法—思路四(The correct way - take four!)

      提供了Blob类型字段后,我们的函数应返回ADOBlobStream中FFD8字符串的位置。ReadBuffer(读缓冲区)从流中一个字节一个字节的读取数据。对ReadBuffer的每个调用都会一个字节一个字节的移动流的位置。当两个字节一起引出SOI标记时,函数返回流的位置。这是这个函数:

   function JpegStartsInBlob(PicField:TBlobField):integer;
   var
    bS     : TADOBlobStream;
    buffer : Word;
    hx     : string;
   begin
    Result := -1;
    bS := TADOBlobStream.Create(PicField, bmRead);
    try
     while (Result = -1) and (bS.Position + 1 < bS.Size) do
     begin
      bS.ReadBuffer(buffer, 1);
      hx:=IntToHex(buffer, 2);
      if hx = FF then begin
       bS.ReadBuffer(buffer, 1);
       hx:=IntToHex(buffer, 2);
      if hx = D8 then Result := bS.Position - 2
       else if hx = FF then
             bS.Position := bS.Position-1;
      end; //if
     end; //while
     finally
      bS.Free
     end;  //try
   end;
   一旦我们有了SOI标记的位置,我们就能使用它在ADOBlob流中找到图片的位置。
     uses jpeg;
     ...
     procedure TForm1.btnShowImageClick(Sender: TObject);
     var
      bS  : TADOBlobStream;
      Pic : TJpegImage;
     begin
      bS := TADOBlobStream.Create(AdoTable1Picture, bmRead);
      try
       bS.Seek(JpegStartsInBlob(AdoTable1Picture),soFromBeginning);
       Pic:=TJpegImage.Create;

		
	
补充:软件开发 , Delphi ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,