问题描述:在form上放一个 TImage控件(Image1),一个 Button 控件, 加入 JPEG单元,
当按下此 button 时,执行如下代码 Stream.LoadFromFile('d:\kk.jpg'); // d:\kk.jpg 存在
Image1.Picture.Graph.LoadFromStream(Stream); <= 此句出错,意思是说地址存取出错 而如果此Image1事先装载有任何一张图片,然后 Image1.Picture.Graph.LoadFromStream(Stream) 则执行正确我估计出错的原因是image1没有生成一个picture或Graph的实例,导致地址存取失败,请问如何解决之.(请不要回答说事先加载一张图片).
程序根据图形文件的属性,在流文件的头上写入属性和文件长,而后再写入数据库,从数据库中读出数据后根据图形文件的格式,调用相应的驱动。此程序原是写来自用的,觉得我的思路和他的有很大的不同,希望对大家有点启发,有任何问题,概不负责。LSI.DMF
object Form1: TForm1
Left = 256
Top = 115
Width = 452
Height = 380
Caption = ’Form1’
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = ’MS Sans Serif’
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Image1: TImage
Left = 152
Top = 24
Width = 145
Height = 177
Stretch = True
end
object ButtonLoadImg: TButton
Left = 56
Top = 272
Width = 105
Height = 25
Caption = ’Load Img To DB’
TabOrder = 0
onClick = ButtonLoadImgClick
end
object ButtonSaveImg: TButton
Left = 264
Top = 272
Width = 113
Height = 25
Caption = ’Read Img From DB’
TabOrder = 1
onClick = ButtonSaveImgClick
end
object ADOConnection1: TADOConnection
Connected = True
ConnectionString =
’Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security In’ +
’fo=False;Initial Catalog=MYDB;Use Procedure for Prepare=1;Auto T’ +
’ranslate=True;Packet Size=4096;Workstation ID=MY-SERVER;Use E’ +
’ncryption for Data=False;Tag with column collation when possible’ +
’=False’
LoginPrompt = False
Mode = cmShareDenyNone
Provider = ’SQLOLEDB.1’
Left = 32
Top = 40
end
object ADOTable1: TADOTable
Connection = ADOConnection1
CursorType = ctStatic
TableName = ’Img’
Left = 32
Top = 80
end
object OpenPictureDialog1: TOpenPictureDialog
Left = 32
Top = 128
end
end//……………………………………………………………………………………..
LSI.PAS
unit LSI;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Db, ADODB, Jpeg, ExtDlgs, LoadSaveImg;type
TForm1 = class(TForm)
Image1: TImage;
ButtonLoadImg: TButton;
ButtonSaveImg: TButton;
ADOConnection1: TADOConnection;
ADOTable1: TADOTable;
OpenPictureDialog1: TOpenPictureDialog;
procedure FormCreate(Sender: TObject);
procedure ButtonLoadImgClick(Sender: TObject);
procedure ButtonSaveImgClick(Sender: TObject);
private
TS: TMemoryStream;
LSI: TLSImg;
end;var
Form1: TForm1;implementation{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject);
begin
if not ADOTable1.Active then
ADOTable1.Active := True;
end;procedure TForm1.ButtonLoadImgClick(Sender: TObject);
var
FName, FType: string;
begin
OpenPictureDialog1.Filter := GraphicFilter(TGraphic);
if OpenPictureDialog1.Execute then
begin
FName := OpenPictureDialog1.Files.Strings[0];
FType := Copy(FName, LastDelimiter(’.’, FName) + 1, Length(Fname) - LastDelimiter(’.’, Fname));
LSI := TLSImg.Create;
if LSI.GetImgType(FType) <> 0 then
begin
TS := TMemoryStream.Create;
LSI.Picture.Graphic.LoadFromFile(FName);
LSI.SaveToStream(TS);
with ADOTable1 do
begin
try
Append;
(Fields[1] as TBlobField).LoadFromStream(TS);
Post;
except
raise
end;
end;
TS.Free;
end;
LSI.Free;
end;
end;procedure TForm1.ButtonSaveImgClick(Sender: TObject);
begin
with ADOTable1 do
begin
if not Eof then
begin
LSI := TLSImg.Create;
TS := TMemoryStream.Create;
(Fields[1] as TBlobField).SaveToStream(TS);
LSI.LoadFromStream(TS);
Image1.Picture := LSI.Picture;
TS.Free;
LSI.Free;
end;
end;
end;
end.
//…………………………………………………………………………………..
LoadSaveImg.Pasunit LoadSaveImg;interface
uses
SysUtils, Classes, Graphics, Jpeg, DB, ADODB;//这里的图形属性顺序是随意安排的,可自行修改,现在的顺序和FastReport相同,在FastReport中打印图像//时可用返回的图形属性设置 FastReport 的Picture 组件的 BlobType。
//procedure TForm1.frReportBeforePrint(Memo: TStringList; View: TfrView);
//begin
// if (View is TfrPictureView) and ((View as TfrPictureView).Name = ’Picture1’) then
// begin
// (View as TfrPictureView).BlobType := LSImg.LoadFromStream(Stream);
// (View as TfrPictureView).Picture.Assign(LSImg.Picture1.Picture);
// end;
//end;const
pkBitmap = 0;
pkJPEG = 1;
pkIcon = 2;
pkMetafile = 3;
pkNone = 4;type
TLSImg = class(TObject)
private
public
Picture: TPicture;
Graphic: TGraphic;
constructor Create;
destructor Destroy; override;
function GetImgType(const FileType: string): Byte;
function LoadFromStream(Stream: TMemoryStream): byte;
function SaveToStream(Stream: TMemoryStream): byte;
end;implementationconstructor TLSImg.Create;
begin
Picture := TPicture.Create;
inherited Create;
end;destructor TLSImg.Destroy;
begin
Picture.Free;
inherited Destroy;
end;//根据输入的文件类型调用相应的驱动程序function TLSImg.GetImgType(const FileType: string): Byte;
begin
Result := pkNone;
if FileType <> ’’ then
if UpperCase(FileType) = ’BMP’ then
Result := pkBitmap
else if (UpperCase(FileType) = ’EMF’) or (UpperCase(FileType) = ’WMF’) then
Result := pkMetafile
else if UpperCase(FileType) = ’ICO’ then
Result := pkIcon
else if (UpperCase(FileType) = ’JPE’) or (UpperCase(FileType) = ’JPG’) or
(UpperCase(FileType) = ’JPEG’) then
Result := pkJPEG;
Graphic := nil;
case Result of
pkBitmap: Graphic := TBitmap.Create;
pkMetafile: Graphic := TMetafile.Create;
pkIcon: Graphic := TIcon.Create;
pkJPEG: Graphic := TJPEGImage.Create;
end;
if Graphic <> nil then
begin
Picture.Graphic := Graphic;
Graphic.Free;
end;
end;//从文件头读图像的种类,然后加载相应的驱动,这里文件长度暂时没有使用
function TLSImg.LoadFromStream(Stream: TMemoryStream): byte;
var
n: Integer;
begin
Stream.Seek(0, soFromBeginning);
//读文件属性
Stream.Read(Result, 1);
//读文件长
Stream.Read(n, 4);
Graphic := nil;
//调用相应的驱动
case Result of
pkBitmap: Graphic := TBitmap.Create;
pkMetafile: Graphic := TMetafile.Create;
pkIcon: Graphic := TIcon.Create;
pkJPEG: Graphic := TJPEGImage.Create;
end;
Picture.Graphic := Graphic;
if Graphic <> nil then
begin
Graphic.Free;
Picture.Graphic.LoadFromStream(Stream);
end;
end;//将图像的属性写入Offset 0 位,长一个字节。文件长写入 Offset 1,长四个字节。
function TLSImg.SaveToStream(Stream: TMemoryStream): byte;
var
n, o: Integer;
begin
Result := pkNone;
//确定图像的属性
if Picture.Graphic <> nil then
if Picture.Graphic is TBitmap then
Result := pkBitmap
else if Picture.Graphic is TMetafile then
Result := pkMetafile
else if Picture.Graphic is TIcon then
Result := pkIcon
else if Picture.Graphic is TJPEGImage then
Result := pkJPEG;
Stream.Seek(0, soFromBeginning);
//在 Offset 0位置上写入图像属性,字长1 Byte。
Stream.Write(Result, 1);
n := Stream.Position;
Stream.Write(n, 4);
if Result <> pkNone then
Picture.Graphic.SaveToStream(Stream);
o := Stream.Position;
Stream.Seek(n, soFromBeginning);
//在 Offset 1位置上写入图像的长度,字长 4 Byte。
Stream.Write(o, 4);
Stream.Seek(0, soFromBeginning);
end;end.
解决问题的办法是Stream.Position := 0;
然后再用image装载
解决问题的办法是Stream.Position := 0;=> 此解无效,
另,我试了一下,果然, Image1.Picture.Graphic 没有实例.
if Assigned(Image1.Picture.Graphic) then
Caption := 'YES'
else
Caption := 'NO';此时,Caption的值是'NO',可以证明Graphic没有实例.
TO : Kerac(痛,很痛,但还是深深的爱你,默默的。) 谢谢你给出的代码.我看看能否实现.
Stream.Position:=0
begin
FGraphic.Free;
inherited Destroy;
end;