怎样在sqlserver2000存取图片,解决了即给分,谢谢 ( 积分: 300 )

  • 主题发起人 主题发起人 xiaolongmao
  • 开始时间 开始时间
X

xiaolongmao

Unregistered / Unconfirmed
GUEST, unregistred user!
我用的是ado+delphi6.想把图片保存在数据中,同时也可以把查询的图片显示出来.
应该怎样做呢,能不能帮我贴出原码呢,谢谢各位的回答
 
库中字段为Image型


//写入图片:
var
JPEG:TJPEGImage;
begin
with Qry1 do
begin
SQL.Clear;
SQL.Append('INSERT INTO AA(A1)');
SQL.Append('VALUES(:A1)');
if Img1.Picture.Graphic<>nil then
begin
try
if Image1.Picture.Graphic<>nil then
begin
JPEG.Assign(Image1.Picture);
Parameters.ParamByName('A1').Assign(JPEG);
end
else
Parameters.ParamByName('A1').Assign(nil);
finally
JPEG.Free;
end;
end;
ExecSQL;
SQL.Clear;
end;
end;


//显示照片
var
JPEG:TJPEGImage;
begin
with Qry1 do
begin
SQL.Clear;
SQL.Append('SELECT A1 FROM AA');
Open;
if not FieldByName('A1').IsNull then
begin
JPEG:=TJPEGImage.Create;
try
JPEG.Assign(FieldByName('A1'));
Image1.Picture.Assign(JPEG);
finally
JPEG.Free;
end;
end
else
Image1.Picture.Assign(nil);
SQL.Clear;
end;
end;
 
已经帮你调试过,没问题,这里用的是bmp图片
代码如下

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, DBGrids, DB, ADODB, StdCtrls, DBCtrls;

type
TForm1 = class(TForm)
DataSource1: TDataSource;
ADOQuery1: TADOQuery;
DBGrid1: TDBGrid;
OpenDialog1: TOpenDialog;
Button1: TButton;
Button2: TButton;
DBImage1: TDBImage;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses DateUtils;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
with ADOQuery1 do
begin
close;
SQL.Text:= 'select * from Tpic';
ADOQuery1.Open;
end;

DBImage1.DataSource:= DataSource1;
DBImage1.DataField:= 'pic';
end;

//显示
procedure TForm1.Button1Click(Sender: TObject);
var
aBitmap: TBitmap;
aStream: TStream;
begin
aBitmap:= TBitmap.Create;
aStream:= TMemoryStream.Create;
try
TBlobField(ADOQuery1.FieldByName('pic')).SaveToStream(aStream);
aBitmap.LoadFromStream(aStream);
finally
aBitmap.Free;
aStream.Free;
end;
end;

//添加
procedure TForm1.Button2Click(Sender: TObject);
var
aBitmap: TBitmap;
begin
aBitmap:= TBitmap.Create;
try
if OpenDialog1.Execute then
with ADOQuery1 do
begin
Append;
TBlobField(FieldByName('pic')).LoadFromFile(OpenDialog1.FileName);
post;
end;
finally
aBitmap.Free;
end;
end;

end.
 
哦,对了,我的数据库是这样的:
id varchar(50)
name varchar(50)
pic image(16)

如果你的数据库不是这样的,你只要稍微改下程序即可,但最主要的是解决关键问题的方法都是一样的
 
解决数据库中图片的问题,关键技术如下:

在数据库上使用Image二进制字段保存,使用Stream流的方式。
创建文件流:
Word_FileStream:=TFileStream.Create(Target_Name,fmOpenWrite or fmCreate);
Word_FileStream.Position:=0;

保存到数据库的Image字段:
TBlobField(AdoQuery1.FieldByName(Column_Name)).SaveToStream(Word_FileStream);

从数据库读取文件到本地硬盘:
TBlobField(ADOQuery1.FieldByName(Column_Name)).loadfromStream(Word_FileStream);

释放文件流:
Word_FileStream.Free;


创建文件流:
Word_FileStream:=TFileStream.Create(Target_Name,fmOpenWrite or fmCreate);
Word_FileStream.Position:=0;

保存到数据库的Image字段:
TBlobField(AdoQuery1.FieldByName(Column_Name)).SaveToStream(Word_FileStream);

从数据库读取文件到本地硬盘:
TBlobField(ADOQuery1.FieldByName(Column_Name)).loadfromStream(Word_FileStream);

释放文件流:
Word_FileStream.Free;

Server中该字段的数据类型是Image,在Access中该字段的数据类型是OLE对象。...

既然你已经用TDBImage控件使用Picture.LoadFromFile装入了图片,
只要该图片字段和TDBimage控件相连了,直接用adodataset.post,就保存到了
数据库。
如果没有相连,可以直接用
Tblobfield(adodataset.fields[字段名]).loadfromfile
从文件中读,或
Tblobfield(adodataset.fields[字段名]).loadfromstream
从stream中读,
要读出该字段内容,用相应的savetofile,savetostream就行了
 
注意如果是jpeg图片,要引用 jpeg单元,即: uses jpeg;
 
给你一个自己作的,现在正在使用,经过实践考验的,你应该能从里面提取出来你需要的东西.希望对你有帮助.

存:
procedure TFrmYGK.BitBtn1Click(Sender: TObject);
var
strm: TMemoryStream;
STRSQL: String;
str:string;
begin
OPD1.Filter:='*.jpg|*.jpg|*.jpeg|*.jpeg';
WITH ADOqryall do
begin
close;
sql.Clear;
sql.Add('select * from 客户 where 客户编号='''+ADOqrytg.fieldbyname('客户名').AsString+'''');
open;
end;
OPD1.InitialDir:='f:/图稿/'+''+ADOqryall.FieldByName('公司名称').AsString+'';

if OPD1.Execute then
begin
Image1.Picture.LoadFromFile(OPD1.FileName );
strm := tmemorystream.Create ;
strsql:='update 图稿库 set 图稿=:a ,BS=:b where id='''+adoqrytg.fieldbyname('id').AsString+''';';
str:=adoqrytg.fieldbyname('id').AsString;
with adoqryall do
begin
close;
sql.Clear;
sql.Text:=strsql;
end;
try
image1.Picture.Graphic.SaveToStream(strm);
adoQrytg.Edit ;
strm.Position :=0;
adoqryall.Parameters[0].LoadFromFile(OPD1.FileName,ftGraphic);
adoqryall.Parameters[1].Value:=1;
adoqryall.ExecSQL;
adoqrytg.Close;
adoqrytg.Open;
adoqrytg.Locate('id',str,[loCaseInsensitive]);
finally
strm.Free;
end;
end;
end;


:(为了能完全显示图片.我把读出的图片放到image控件中了)
procedure TFrmYGK.ADOQrytgAfterScroll(DataSet: TDataSet);
var
strm: TADOBlobStream;
bl,bl1:double;
begin
strlx1:=adoqrytg.fieldbyname('标类型').AsString;
if adoqrytg.FieldByName('BS').AsInteger =1 then
begin
{ with adoqryall2 do
begin
close;
sql.Clear;
sql.Add('select 图稿 from 图稿库 where id='''+adoqrytg.fieldbyname('ID').AsString+'''');
OPEN;
end; }
strm := tadoblobstream.Create(tblobfield(adoqrytg.fieldbyname('图稿')),bmread);
//strm := tadoblobstream.Create(tblobfield(adoqryALL2.fieldbyname('图稿')),bmread);
try // try1
strm.position :=0;
image1.Picture.Graphic := nil; //清除图像
jpegimage := tjpegimage.Create ;
try //try12
jpegimage.LoadFromStream(strm);
image1.Picture.Graphic := jpegimage;
if RadioButton2.Checked=true then
begin
image1.Height:=image1.Picture.Height;
image1.Width:=image1.Picture.Width;
end
else if radiobutton1.Checked=true then
begin
if (image1.Picture.Width>ScrollBox1.Width) and (image1.Picture.Height>ScrollBox1.Height) then
begin
bl:=image1.Picture.Width/ScrollBox1.Width;
bl1:=image1.Picture.Height/scrollbox1.Height;
if bl<bl1 then
begin
image1.Height:=scrollbox1.Height;
image1.Width:=floor(image1.Picture.Width/bl1);
end
else
begin
image1.Width:=scrollbox1.Width;
image1.Height:=floor(image1.Picture.Height/bl);
end;
end
else if (image1.Picture.Width>ScrollBox1.Width) and (image1.Picture.Height<=ScrollBox1.Height) then
begin
bl:=image1.Picture.width/scrollbox1.Width;
image1.Width:=scrollbox1.Width;
image1.Height:=floor(image1.Picture.Height/bl);
end
else if (image1.Picture.Width<=ScrollBox1.Width) and (image1.Picture.Height>ScrollBox1.Height) then
begin
bl:=image1.Picture.height/scrollbox1.height;
image1.height:=scrollbox1.height;
image1.width:=floor(image1.Picture.width/bl);
end
else
begin
image1.Height:=image1.Picture.Height;
image1.Width:=image1.Picture.Width;
end;

end
else if radiobutton3.Checked=true then
begin
image1.Align:=alclient;
image1.Stretch:=true;
end;
intheight:=jpegimage.Height;
intwidth:=jpegimage.Width;
finally
jpegimage.Free ;
end; //end try12
finally
strm.Free ;
end; //end try1
end
else
begin
image1.Picture.Graphic:=nil;
end;
image1.Stretch:=true;
end;
 
上面大家说的已经够详细了,但都没有提到BMP和JPG都要保存的情况,我现在来说说我的方法,因为JPG和BMP都有固定的文件头,所以在读取的时候,可以先进行判断,然后再使用对应的方法进行处理。
procedure TForm1.qAfterScroll(DataSet: TDataSet);
Const
JPGPRE = 'D8FF';
BMPPRE = '4D42';
Var
Stream : TMemoryStream;
bmp:TBitmap;
jpg:TJpegImage;
A : Array[0..1] of char;
T : Word;
S : String;
begin
Stream := TMemoryStream.Create;
jpg := TJpegImage.Create;
BMP := TBitmap.Create;
Try
TBlobField(Q.FieldByName('pic')).SaveToStream(Stream);
Stream.Position := 0;
Stream.Read(T,2);
Stream.Position := 0;
S := IntToHex(T,2);
if S = BMPPRE then
begin
BMP.LoadFromStream(Stream);
Image1.Picture.Assign(BMP);
end
else if S = JPGPRE then
begin
JPG.LoadFromStream(Stream);
Image1.Picture.Assign(JPG);
end;
Finally
Stream.Free;
jpg.Free;
BMP.Free;
End;
end;
 
楼上已很详细
 
综合以上,既能识别bmp又识别读jpeg,我把代码修改如下:
(建议用image,不要用dbimage控件,因为该控件只能识别bmp格式图片)
(程序已调试,运行正确 delphi7 + sql server 2000)

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Grids, DBGrids, DB, ADODB, StdCtrls, DBCtrls;

type
TForm1 = class(TForm)
DataSource1: TDataSource;
ADOQuery1: TADOQuery;
DBGrid1: TDBGrid;
OpenDialog1: TOpenDialog;
Button1: TButton;
Button2: TButton;
DBImage1: TDBImage;
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses DateUtils,jpeg;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
with ADOQuery1 do
begin
close;
SQL.Text:= 'select * from Tpic';
ADOQuery1.Open;
end;

//DBImage1.DataSource:= DataSource1;
//DBImage1.DataField:= 'pic';
end;

//显示
procedure TForm1.Button1Click(Sender: TObject);
var
aBitmap: TBitmap;
aJPEGImage: TJPEGImage;
aStream: TStream;
head: word;
const
bmp = $4D42;
jpeg = $D8FF;
begin
aBitmap:= TBitmap.Create;
aJPEGImage:= TJPEGImage.Create;
aStream:= TMemoryStream.Create;
try
TBlobField(ADOQuery1.FieldByName('pic')).SaveToStream(aStream);

aStream.Position := 0; //一定要有这句
aStream.Read(head,2);
aStream.Position:= 0;
if head = bmp then
begin
aBitmap.LoadFromStream(aStream);
Image1.Picture.Assign(aBitmap);
end
else if head = jpeg then
begin
aJPEGImage.LoadFromStream(aStream);
Image1.Picture.Assign(aJPEGImage);
end;

finally
aBitmap.Free;
aJPEGImage.Free;
aStream.Free;
end;
end;

//添加
procedure TForm1.Button2Click(Sender: TObject);
var
aBitmap: TBitmap;
aJPEGImage: TJPEGImage;
aStream: TStream;
begin
aBitmap:= TBitmap.Create;
aJPEGImage:= TJPEGImage.Create;
aStream:= TMemoryStream.Create;

try
if OpenDialog1.Execute then
begin
if ExtractFileExt(OpenDialog1.FileName)= '.bmp'then
begin
aBitmap.LoadFromFile(OpenDialog1.FileName);
aBitmap.SaveToStream(aStream);
end
else if (ExtractFileExt(OpenDialog1.FileName)= '.jpg') or (ExtractFileExt(OpenDialog1.FileName)= '.jpeg') then
begin
aJPEGImage.LoadFromFile(OpenDialog1.FileName);;
aJPEGImage.SaveToStream(aStream);
end;

with ADOQuery1 do
begin
Append;
aStream.Position:= 0;
TBlobField(FieldByName('pic')).LoadFromStream(aStream);//出错的地方:原来是因为我用了dbimage控件,该控件只能显示bmp格式图片
Post;
end;
end;
finally
aBitmap.Free;
aJPEGImage.Free;;
aStream.Free;
end;
end;

end.
 
图片问题 。
主要有两种思路:
1。图片文件保存到数据库:这种方法是将图片文件以二进制形式保存。这种方法不但可以保存图片还可以保存电影啊优点:保密性强;致命缺点:如果图片很多会造成数据库臃肿。
2。保存图片的绝对路径
这种方法只是保存文件的绝对路径到数据库,在访问时读取路径然后。。
优点:简单,快速 缺点:保密问题比较突出(误操作等)
建议: 如果图片数量不是很大建议内部保存

用DBImage控件只能显示bmp图像,一个图像用bmp格式要用0.5M-几M空间,jpeg格式只有几十至几百kB。如果图片较多,用DBImage控件显示,其程序大小是个问题。
一个程序保密要性强,也要考虑安装问题,保存图片的绝对路径,是否考虑安装的盘符。

强烈建议:用jpeg格式图像,数据库内部保存,image显示。
 
建议将图片文件以二进制形式保存,空间大
 
呵呵,我刚想到的方法就被楼下的发扬光大,开心。
我现在明白了,要想有收获,就要加大投入,楼主投入了300币,收获果然大 [:D]
 
呵呵,值的收藏的帖子。
 
实例:http://www.erp2.cn/PICList.rar
 
将图片文件以二进制形式保存在數据庫中,這樣操作方便些、更保密些
 
差不多全了,不错!
 
哇,说解决了即给分,都n天了还没反应,
楼主不是想赖账啊 ^_^
 
解决了后, 就忘了来这里了吧.呵呵
 
后退
顶部