呼び出していますが、事前に有効な派生オブジェクトでプロパティをTGraphic.LoadFromStream()
初期化していないため、プロパティがクラッシュする可能性があります。TPicture.Graphic
TGraphic
nil
また、 を に保存するTPicture.Graphic
場合TMemoryStream
、DB に保存するときにグラフィックの最初のバイトをスキップしています。すべてのバイトが重要なので、スキップしないでください。
画像が具体的には JPEG であり、他に何もないと仮定すると (保存コードはファイルの種類を制限していません)、代わりにこれを試してください:
procedure TfrmMain.btnAddPickT4Click(Sender: TObject);
var
S : TMemoryStream;
ikode : integer;
begin
if cbxDeelnemerT4.ItemIndex < 0 then
begin
MessageDlg('Kies asseblief ''n deelnemer!',mtInformation,[mbOK],1);
Exit;
end;
if not OpenPictureDialog1.Execute then
Exit;
Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
if not (Image1.Picture.Graphic is TJpegImage) then
raise Exception.Create('Sorry, only JPG images can be saved in the DB');
ikode := cbxDeelnemerT4.ItemIndex + 1;
S := TMemoryStream.Create;
try
Image1.Picture.Graphic.SaveToStream(S);
S.Position := 0;
ADOQuery1.Close;
ADOQuery1.SQL.Text := 'SELECT * FROM DEELNEMERS WHERE Kode = '+IntToStr(ikode);
ADOQuery1.Open;
ADOQuery1.Insert;
try
TBlobField(ADOQuery1.FieldByName('Foto')).LoadFromStream(S);
ADOQuery1.Post;
except
ADOQuery1.Cancel;
raise;
end;
finally
S.Free;
end;
end;
uses
..., Jpeg;
procedure TfrmMain.btnOpenProfileT4Click(Sender: TObject);
var
S : TMemoryStream;
ikode : integer;
Jpg: TJPEGImage;
begin
ikode := cbxDeelnemerT4.ItemIndex + 1;
ADOQuery1.Close;
ADOQuery1.SQL.Text := 'SELECT * FROM DEELNEMERS WHERE Kode = ' + IntToStr(ikode);
ADOQuery1.Open;
S := TMemoryStream.Create;
try
TBlobField(ADOQuery1.FieldByName('Foto')).SaveToStream(S);
S.Position := 0;
Jpg := TJPEGImage.Create;
try
Jpg.LoadFromStream(S);
Image1.Picture.Assign(Jpg);
finally
Jpg.Free;
end;
finally
S.Free;
end;
end;
ただし、画像が JPEG 以外の形式である可能性がある場合は、画像タイプを DB に保存して、それを読み戻して正しいTGraphic
クラス タイプ ( TBitmap
、TJpegImage
、TGifImage
、TPNGImage
など) をインスタンス化し、必要に応じて処理できるようにする必要があります。例えば:
procedure TfrmMain.btnAddPickT4Click(Sender: TObject);
var
S : TMemoryStream;
ikode : integer;
begin
if cbxDeelnemerT4.ItemIndex < 0 then
begin
MessageDlg('Kies asseblief ''n deelnemer!',mtInformation,[mbOK],1);
Exit;
end;
if not OpenPictureDialog1.Execute then
Exit;
Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
ikode := cbxDeelnemerT4.ItemIndex + 1;
S := TMemoryStream.Create;
try
Image1.Picture.Graphic.SaveToStream(S);
S.Position := 0;
ADOQuery1.Close;
ADOQuery1.SQL.Text := 'SELECT * FROM DEELNEMERS WHERE Kode = '+IntToStr(ikode);
ADOQuery1.Open;
ADOQuery1.Insert;
try
// this is just an example, there are other ways to do this
if Image1.Picture.Graphic is TJPEGImage then
ADOQuery1.FieldByName('FotoType').AsString := 'jpg'
else if Image1.Picture.Graphic is TPNGImage then
ADOQuery1.FieldByName('FotoType').AsString := 'png'
else if Image1.Picture.Graphic is TGIFImage then
ADOQuery1.FieldByName('FotoType').AsString := 'gif'
else if Image1.Picture.Graphic is TBitmap then
ADOQuery1.FieldByName('FotoType').AsString := 'bmp'
else
raise Exception.Create('Cannot save unsupported image type to DB');
TBlobField(ADOQuery1.FieldByName('Foto')).LoadFromStream(S);
ADOQuery1.Post;
except
ADOQuery1.Cancel;
raise;
end;
finally
S.Free;
end;
end;
uses
..., Jpeg, GifImg, PngImg;
procedure TfrmMain.btnOpenProfileT4Click(Sender: TObject);
var
S : TMemoryStream;
ikode : integer;
Graphic: TGraphic;
GraphicType: String;
begin
ikode := cbxDeelnemerT4.ItemIndex + 1;
ADOQuery1.Close;
ADOQuery1.SQL.Text := 'SELECT * FROM DEELNEMERS WHERE Kode = ' + IntToStr(ikode);
ADOQuery1.Open;
S := TMemoryStream.Create;
try
TBlobField(ADOQuery1.FieldByName('Foto')).SaveToStream(S);
S.Position := 0;
GraphicType := ADOQuery1.FieldByName('FotoType').AsString;
if GraphicType = 'jpg' then
Graphic := TJPEGImage.Create
ADOQuery1.FieldByName('FotoType').AsString := 'jpg'
else if GraphicType = 'png' then
Graphic := TPNGImage.Create
else if GraphicType = 'gif' then
Graphic := TGifImage.Create
else if GraphicType = 'bmp' then
Graphic := TBitmap.Create
else
raise Exception.Create('Cannot load unsupported image type from DB');
try
Graphic.LoadFromStream(S);
Image1.Picture.Assign(Graphic);
finally
Graphic.Free;
end;
finally
S.Free;
end;
end;
TBlobField
そうは言っても、直接アクセスするべきではありません。TDataSet.CreateBlobStream()
代わりにメソッドを使用して、ADO が ADO blob データへのアクセス用に最適化されたオブジェクトを提供できるようにしますTStream
。
procedure TfrmMain.btnAddPickT4Click(Sender: TObject);
var
S : TStream;
ikode : integer;
begin
if cbxDeelnemerT4.ItemIndex < 0 then
begin
MessageDlg('Kies asseblief ''n deelnemer!',mtInformation,[mbOK],1);
Exit;
end;
if not OpenPictureDialog1.Execute then
Exit;
Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
ikode := cbxDeelnemerT4.ItemIndex + 1;
ADOQuery1.Close;
ADOQuery1.SQL.Text := 'SELECT * FROM DEELNEMERS WHERE Kode = '+IntToStr(ikode);
ADOQuery1.Open;
ADOQuery1.Insert;
try
...
S := ADOQuery1.CreateBlobStream(ADOQuery1.FieldByName('Foto'), bmWrite);
try
Image1.Picture.Graphic.SaveToStream(S);
finally
S.Free;
end;
ADOQuery1.Post;
except
ADOQuery1.Cancel;
raise;
end;
end;
procedure TfrmMain.btnOpenProfileT4Click(Sender: TObject);
var
S : TStream;
ikode : integer;
Graphic: TGraphic;
begin
ikode := cbxDeelnemerT4.ItemIndex + 1;
ADOQuery1.Close;
ADOQuery1.SQL.Text := 'SELECT * FROM DEELNEMERS WHERE Kode = ' + IntToStr(ikode);
ADOQuery1.Open;
...
Graphic := ...;
try
S := ADOQuery1.CreateBlobStream(ADOQuery1.FieldByName('Foto'), bmRead);
try
Graphic.LoadFromStream(S);
finally
S.Free;
end;
Image1.Picture.Assign(Graphic);
finally
Graphic.Free;
end;
end;