Cześć,
mam taki problem:
Do procedury przekazuję polę TBlobField zawierający zapisany obrazek JPEG, oraz jako drugi parametr właściwość TPicture od komponentu TImage.
Procedura wczytująca obrazek:
procedure TfrmMenu.ShowDBPrintScreen(FieldImagen: TBlobField; Picture: TPicture);
var
Stream: TMemoryStream;
Jpg: TJpegImage;
begin
Jpg := nil;
Stream := nil;
try
Stream := TMemoryStream.Create;
FieldImagen.SaveToStream(Stream);
if Stream.Size>0 then
begin
Jpg := TJpegImage.Create;
Stream.Position := 0;
Jpg.LoadFromStream(Stream);
Picture.Bitmap.Assign(Jpg);
end
else
Picture.Bitmap.Assign(nil);
except
on e:exception do
begin
frmMenu.ShowMessageDlg('Błąd wczytywania obrazu! (ShowDBPrintScreen)#13#13<b>' + e.Message + '</b>', 'err');
Picture.Bitmap.Assign(nil);
end;
end;
jpg.Free;
Stream.Free;
end;
Niestety problem pojawia się przy odczycie większych obrazków, a dokładniej przy przypisywaniu ich do komponentu Image czyli:
Image1.Picture.Assign(jpg);
program na nie całą sekundę się zawiesza na poczet wykonania tej procedury.
Pomyślałem, że mogę to robić w wątku więc zrobiłem to w ten sposób:
type
TThread_ImagePreview = class(TThread)
protected
procedure Execute; override;
private
procedure ShowImagePreview;
public
BlobField: TBlobField;
ImagePreview: TPicture;
end;
procedure TThread_ImagePreview.Execute;
begin
inherited;
NameThreadForDebugging('ImagePreview');
FreeOnTerminate := True;
Synchronize(ShowImagePreview);
end;
procedure TThread_ImagePreview.ShowImagePreview;
begin
frmMenu.ShowDBPrintScreen(BlobField, ImagePreview);
end;
Wątek wywołuję w ten sposób:
procedure button1.OnClick(Sender: TObject);
var
Thread_ImagePreview: TThread_ImagePreview;
begin
// tutaj otwarcie dataseta
....
Thread_ImagePreview := TThread_ImagePreview.Create(True);
Thread_ImagePreview.BlobField := (DataSet.Fields[0] as TBlobField);
Thread_ImagePreview.ImagePreview := img_printscreen.Picture;
Thread_ImagePreview.Resume;
end;
Ale ku mojemu zdziwieniu - zero różnicy. Tak jakby wątek nie zadziałał. Procedura wykonywana jest w dwóch miejscach prawie jednocześnie z tym, że jako parametry dostają inny obrazek.
Czy ktoś może doradzić co robię nie tak? Przyznam, że dopiero zaczynam z wątkami.
@EDITED
//********* ZMODYFIKOWANA WERSJA WĄTKU
type
TThread_ImagePreview = class(TThread)
protected
procedure Execute; override;
private
procedure ShowImagePreview;
public
Table: string;
ID: integer;
ImagePreview: TPicture;
end;
procedure TThread_ImagePreview.ShowImagePreview;
var
Dataset: TIBDataset;
begin
try
Dataset := TIBDataSet.Create(nil);
Dataset.BufferChunks := 10;
Dataset.Database := frmdm.IBDatabase1;
Dataset.Transaction := frmDM.IBTransaction1;
Dataset.DisableControls;
Dataset.Close;
if Table = 'tasks' then
begin
Dataset.SelectSQL.Text := 'select img from tasks where id_t = :id_t and img is not null';
Dataset.ParamByName('id_t').AsInteger := ID;
end
else
begin
Dataset.SelectSQL.Text := 'select print_screen from repository where id_rep = :id_rep';
Dataset.ParamByName('id_rep').AsInteger := ID;
end;
Dataset.Open;
Dataset.EnableControls;
if Table = 'tasks' then
begin
frmMenu.img_printscreen.Picture := nil;
if not Dataset.FieldByName('img').IsNull then
begin
frmMenu.Notebook_RightPanel.ActivePage := 'printscreen';
frmMenu.ShowDBPrintScreen((DataSet.Fields[0] as TBlobField), ImagePreview);
end
else
frmMenu.Notebook_RightPanel.ActivePage := 'empty';
end
else
begin
frmRepository.imgPrintScreen.Picture := nil;
if not Dataset.FieldByName('print_screen').IsNull then
begin
frmRepository.Notebook1.ActivePage := 'printscreen';
frmMenu.ShowDBPrintScreen((DataSet.Fields[0] as TBlobField), ImagePreview);
end
else
frmRepository.Notebook1.ActivePage := 'empty';
end;
FreeAndNil(Dataset);
except
on e:exception do
begin
FreeAndNil(Dataset);
frmMenu.ShowMessageDlg('Błąd wczytywania zrzutu ekranu instrukcji!#13#13<b>' + e.Message + '</b>', 'err');
end;
end;
end;
//********* Wywołanie
Thread_ImagePreview := TThread_ImagePreview.Create(True);
Thread_ImagePreview.ID := Data.ID_REP;
Thread_ImagePreview.Table := 'repository';
Thread_ImagePreview.ImagePreview := imgPrintScreen.Picture;
Thread_ImagePreview.Resume;