通过Delphi在SQL Server2000对BMP图像的存储和读取操作

来源:互联网 发布:华大基因难进吗 知乎 编辑:程序博客网 时间:2024/05/16 12:11

通过Delphi在SQL Server2000对BMP图像的存储和读取操作

---- 在Dephi中提供了一个抽象的数据类型TStream来支持对流式数据的操作。这些数据通常来自文件、数据库、内存对象、OLE对象等,TStream提供了统一、简洁的方法来进行数据的读写。在通常情况下,我们并不需要直接使用TStream类,对流式数据的读写封装在VCL控件的方法中。但是如果这些方法无法满足我们的要求,就需要自己手动控制数据的读写。

一、 TStream的常用的方法和属性:

---- 1. function Read(var Buffer; Count: Longint): Longint; virtual; abstract

---- 2. function Write(const Buffer; Count: Longint): Longint; virtual; abstract;

---- 3. function Seek(Offset: Longint; Origin: Word): Longint; virtual; abstract;

---- 4. property Position: Longint;

---- 5. property Size: Longint



---- Read,Write,Seek都是纯虚函数,提供了数据读写和定位的抽象的方法。Read方法将数据从Stream中读到Buffer缓冲区中,Write则实现相反的操作,返回值表示实际读写数据的大小。Seek提供了在Stream中移动数据指针的方法。参数Origin可以取soFromBeginning,soFromCurrent,soFromEnd 三个值,Offset是偏移量,返回值是当前Stream数据指针的位置。


---- Position表示了数据指针在Stream中的位置。这个属性是可读写的,它实际上就是通过调用Seek方法实现的,所以实际使用时使用这个属性更为方便一些。Size属性表示当前Stream的大小,对于不同的Stream,有些时候是只读的。


二、 Stream数据的读写。

---- 1. SaveToStream(Stream: TStream ); //将类中的数据写到Stream的当前位置中

---- 2. LoadFromStream(Stream: TStream); //从当前位置读入Stream里的数据

---- 实际使用时我们基本上只要使用上面两个函数就可以了。



三、 例子

---- TStream的继承树图Delphi联机帮助(略),实际使用时比较常用的是TFileStream,TMemoryStream,TblobStream,就以这三种流举一例说明具体用法。


---- 创建一个窗体Form1,放置四个按钮btnRead,btnInvert,btnSave,btnDisp和一个文件打开对话框OpenDialog1以及数据控件DataSource1,image1,listbox1,DataSource1,DBNavigator1,他们的属性设置略。定义一个全局变量str(string)。

---- 事件代码编写如下:

---- 1. btnRead的Click事件,这里演示了TFileStream的用法。

var

MS: TFileStream;

begin

if OpenDialog1.Execute then

begin

MS:=TFileStream.Create(OpenDialog1.FileName, fmOpenRead);

Image1.Picture.Bitmap.LoadFromStream(MS);

MS.Free;

end;

end;

--- 2. btnInvert的Click事件,这里演示了TMemoryStream的用法。其中使用了Invert函数,这是一个简单的将图象反色的函数(仅对真彩图象有效),它返回一个指向处理过的图象数据块的指针。

var

MS: TMemoryStream;

pImage: pointer;

begin

MS:=TMemoryStream.create;

Image1.Picture.Bitmap.SaveToStream(MS);

MS.Position:=0;

pImage:=Invert(MS.Memory, MS.size);

//Memory属性是指向实际内存块的指针

MS.Write(pImage^,MS.size);

MS.Position:=0;

//上一行代码使指针移到了Stream末尾,所以要复位

Image1.Picture.Bitmap.LoadFromStream(MS);

FreeMem(pImage);

MS.Free;

end;



Invert函数如下:

function TForm1.Invert(pImage: pointer; size: Integer): pointer;

var

pData, pMem: PChar;

i: Integer;

begin

pMem:=AllocMem(size);

CopyMemory(pMem,pImage,size);

pData:=pMem+54;

for i:=0 to size-54-1 do

begin

pData^:=Char(not integer(pData^));

pData:=pData+1;

end;

Result:=pMem;

end;


--- 3. btnSave的Click事件,这里演示了TMemoryStream的另一种用法,将Stream中的数据写到数据库中去。

var

MS: TMemoryStream;

begin

MS:=TMemoryStream.create;

Image1.Picture.Bitmap.SaveToStream(MS);

MS.Position:=0;

Table1.Append;

//在数据库中添加一条记录

TBlobField(Table1.FieldbyName('image')).LoadFromStream(MS);

Table1.Post;

//将所作的更新写入数据库

end;

--- 4. btnDisp的Click事件,在listbox1中显示数据库中Name字段的值;

 

 with ADOTable1 do
    begin
        First;

        while not eof do
        begin
            listbox1.Items.Add(FieldByName('Name').AsString);
            Next;
        end;
    end;

--- 5. listbox1的双击事件,在image1中读取数据库中相应的图像; 

 

var
    mem:TStream;
    bmp:TBitmap;
begin
    with ADOTable1 do
    begin
        First;
        While not eof do
        begin
            if FieldByName('Name').AsString = listbox1.Items[listbox1.ItemIndex] then
                Break;
            Next;
        end;

        bmp := TBitmap.Create;
        mem := CreateBlobStream(FieldByName('img'),bmRead);
        mem.Position :=0;
        bmp.LoadFromStream(mem);
        self.image1.Picture.Assign(bmp);
        bmp.Free;
        mem.Free;
    end;
end;

 

在Delp7+WinXP下编译通过。