使用BCB在数据库中插入图像及读出图像
文:225732@qq.com 2006-08-19 转载请注明出处
如何在数据库中插入及读出图像内容呢,这个问题困扰了自己很久。通过今天查阅相关资料终于发现一些来龙去脉,特记录下来。
(我所使用的基础数据库系统为MSSQL2000,编程工具是BCB6。)
数据库中除了我们经常使用的基本数据库型(char,int,float,double,string等)外,也能储存一些长度可变的二进制数据,例如图像
(JPG,BMP文件等),在MSSQL中这种数据有三种类型(ntext、text 和 image)可以储存大量可变长度的数据,它们的区别如下(此列表来自
于MSSQL的帮助文件):
ntext、text 和 image用于存储大型非 Unicode 字符、Unicode 字符及二进制数据的固定长度和可变长度数据类型。Unicode 数据使用
UNICODE UCS-2 字符集。
ntext
可变长度 Unicode 数据的最大长度为 2^30 - 1 (1,073,741,823) 个字符。存储大小是所输入字符个数的两倍(以字节为单位)。ntext
在 SQL-92 中的同义词是 national text。
text
服务器代码页中的可变长度非 Unicode 数据的最大长度为 2^31-1 (2,147,483,647) 个字符。当服务器代码页使用双字节字符时,存储量
仍是 2,147,483,647 字节。存储大小可能小于 2,147,483,647 字节(取决于字符串)。
image
可变长度二进制数据介于 0 与 2^31-1(2,147,483,647)字节之间
根据此说明我们可以知道在我们的数据库中如果某个字段要储存图像、声音等二进制数据时可以将此字段的数据类型设定为image。
一 在实际中我们的图像等文件通常是以文件的形式存在于disk的file system中,文件名就是这些数据的标识符(可以理解为文件句柄)
,为了将这JPG文件存储到MSSQL2000中我们可以按以下几个步骤即可完成:
1 将JPG转换成相应的数据流放在内存中。
在BCB的VCL中有一个TMemoryStream类可以将文件读入到内存中形成一个数据流,可以通过它方便地进行数据交换。
2 通过将TField类强制转为TBlobField,利用TBlobField中对于数据流的支持可以在数据库中插入二进制数.
参见下面的实际例子代码说明:
void __fastcall TForm1::SaveToDbClick(TObject *Sender)
{
TMemoryStream * MemoryImageStream=new TMemoryStream; //A
Image1->Picture->Graphic->SaveToStream(MemoryImageStream); //B
ADOTable1->Append(); //C
((TBlobField *) (ADOTable1->FieldByName("MyImage")))->LoadFromStream(MemoryImageStream); //D
ADOTable1->Post(); //E
delete MemoryImageStream; //F
}
代码说明:
这是一个Botton按下的执行代码,它的功能是将Image1这个TImage控件中的图片存入到我数据库的MyImage这个字段中(此字段的数据类型为
image),ADOTable1是TADOTable控件,我已设定好其到数据库中表的连接.
A行建立在内存中建立一个内存数据流对象MemoryImageStream
B行将Image1中的JPG图片内容写入MemoryImageStream
C行将数据表ADOTable1置于追加记录状态.
D行使用ADOTable1中的FieldByName("MyImage")函数设定MyImage字段的内容,因为FieldByNmae()函数返回的是一个Field类指针,为了让其支持
流操作将它强制通过(TBlobField *)完成转换,这样就能通过LoadFromStream(MemoryImageStream)将这个图片数据流存入到MyImage字段中,
E行将缓冲区的数据写入数据库中.
F行删除MemoryImageStream对象.
二 将数据库中的Image型字段读出到我们的程序中显示出来的过程和上面写入的过程很相似,详见下面的例程:
void __fastcall TForm1::ReadImageDBClick(TObject *Sender)
{
TMemoryStream * MemoryImageStream=new TMemoryStream; //A
TJPEGImage *tmpJpeg=new TJPEGImage; //B
ADOTable1->Open(); //C
if((!ADOTable1->FieldByName("MyImage")->IsNull)) //D
{
((TBlobField *)(ADOTable1->FieldByName("MyImage")))->SaveToStream(MemoryImageStream); //E
MemoryImageStream->Position=0; //F
tmpJpeg->LoadFromStream(MemoryImageStream); //G
Image1->Picture->Graphic=tmpJpeg; //H
}
delete MemoryImageStream; //I
delete tmpJpeg; //J
}
代码说明:
这是一个Botton按下的执行代码,它的功能是将数据库中第一条记录的MyImage这个Image字段的内容读出,通过Image1这个TImage控件来图示出
图片内容,其它设定请参照上段说明.
A行建立在内存中建立一个内存数据流对象MemoryImageStream
B行建立一个TJPEGImage对象来存入jpg图像数据.
C行打开表
D行如果MyImage字段中没有数据则不进行{E F G H}这几个动作
E行使用ADOTable1中的FieldByName("MyImage")函数获取MyImage字段的内容,因为FieldByNmae()函数返回的是一个Field类指针,为了让其支持
流操作将它强制通过(TBlobField *)完成转换,这样就能通过SaveToStream(MemoryImageStream)将这个图片数据流存入到MemoryImageStream这
个对象中.
F行将MemoryImageStream的数据定位标记移到数据最前端
G行将这个JPG数据流的内容存入TJPEGImage对象tmpJpeg中.
H行将Image1这个控件的图像内容设定为tmpJpeg的内容,图像即可显示在我们的窗口中.
I和J行分别清除不用的临时对象.
以上分析只是一个最简单的模型,很多细节暂时没有去完善.
使用BCB在数据库中插入图像及读出图像
最新推荐文章于 2022-01-16 16:30:17 发布