使用BCB在数据库中插入图像及读出图像
2013-08-01 08:26
253 查看
使用BCB在数据库中插入图像及读出图像
使用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在数据库中插入图像及读出图像
- 开归档的数据库,使用append 插入是否该表可以不写日志?
- 使用SqlBulkCopy将DataTable中的数据批量插入数据库中
- 使用mybatis批量插入数据库自动生成主键
- XCode使用记录—使用XCode自动向数据库插入测试数据
- 使用jdbc向数据库插入100000条记录
- SQL语言使用insert语句向数据库表格中插入或添加新的数据行
- 关于使用FMDB往数据库里插入空字符串@""后,再读出来是什么东西的问题
- mysql 使用 mybatis向数据库表中插入中文,显示???
- 使用 SqlBulkCopy大批量插入数据到数据库
- 使用SQLiteHelper创建数据库并插入数据
- 使用GridView控件在数据库中插入数据
- C#使用SqlBulkCopy将DataTable写入数据库的表中(表不存在则创建新表,数据存在则更新,不存在则插入)
- 向数据库插入使用分隔符分隔(任意分隔符)的字符串脚本
- Slatstack高级技巧(二) 使用django解析salt-api获取的信息插入数据库
- 使用sql语句向数据库插入数据,不受错误数据影响
- 使用linq插入数据库所在服务器的时间
- 在Java中使用JDBC向数据库插入图片和读取数据库中的图片(八)
- 使用PDO连接数据库 查询和插入乱码的解决方法
- 使用mybatis向数据库插入不进数据并且不报错