Newsgroup: it.comp.lang.delphi
Titolo: funzioni da mettere in un thread

Ho fatto una piccola applicazione che analizza in modo un po' barbaro delle
immagini
Ho scritto per lo scopo delle funzioni che prendono in ingresso una matrice
e ne danno in uscita un'altra
il problema č che ogni funzione quando parte occupa al 100% la cpu per quasi
un secondo e mi impalla il resto dell'applicazione che nel frattempo
dovrebbe visualizzare dei dati che gli arrivano dalla porta seriale o
comunque dovrebbe rispondere ai miei comandi
Ho pensato di mettere ste funzioni in dei thread ma non ho la piů pallida
idea di come si possa fare e l'esempio fornito da Delphi non mi ha chiarito
un fico secco (certo che perň il quick sort č davvero quick!)
Mi date una mano almeno per l'ossatura della cosa?
PS Puň aiutare se vi dico che ho una immagine sulla form e tramite canvas me
la ricopio su una matrice, elaboro con una delle funzioni e poi ricopio la
matrice sul canvas? Potrei avere problemi di sincronizzazione?
--
_________________________________________
Edmondo Di Tucci snar...@Ttin.it
guarda i miei lavori su: 
www.powernetsi.it/edmondo

 sincronizzazione?
Dovrai sincronizzare (metodo Synchronize) l'aggiornamento finale della
TImage...
Per il resto ti basta scriverti una classe discendente da TThread che
comprenda il codice con cui fai la trasformazione sull'immagine, creare
un'istanza sospesa (CreateSuspended=True) di quella classe, passargli (in
copia) l'immagine originale e lanciare il thread (Resume) e mettere nel
metodo Execute il codice con cui fai le operazioni sull'immagine.
L'ultima istruzione di Execute sarà fare una chiamata (usando Synchronized)
ad un metodo della form "normale" in cui aggiornerai l'immagine (passa il
riferimento al thread oppure passa come parametro l'immagine di output).
Non so se si capisce molto, sarebbe più chiaro lavorando su del codice!
(posta pure)
Ciao
--
Andrea /\/\agni
ICQ#: 174108000

 ha scritto nel messaggio
news:PM41b.117847$cl3.3...@news2.tin.it...


 PS Può aiutare se vi dico che ho una immagine sulla form e tramite canvas


 (posta pure)
Allora posto, che è meglio!
Commento un po' sto frammento di codice
Sono 4 blocchi strutturati in maniera molto simile che prendono l'immagine,
la elaborano, la mettono a video e salvano l'immagine in un file
Bordi.Picture.Bitmap:=FrameData.Bitmap; //piglio l'immagine da un componente
che acchiappa dalla scheda tv
GetImage(Bordi.Canvas, Mappa); //copio l'immagine su una matrice
StatusBar.Panels[0].Text := 'Smoothing con Gauss...';
frmEdgeCapture.Repaint;
Mappa:=Smooth(Mappa); // la prima funzione incriminata
SetImage(Bordi.Canvas, Mappa); //ricopio la matrice sul canvas per vedere
che ha fatto
Bordi.Picture.SaveToFile('c:\Gauss.bmp');
StatusBar.Panels[0].Text := 'Calcolo Gradiente...';
frmEdgeCapture.Repaint;
Mappa:=Gradiente(Mappa);
SetImage(Bordi.Canvas, Mappa);
Bordi.Picture.SaveToFile('c:\Gradiente.bmp');
StatusBar.Panels[0].Text := 'NonMaxSuppression...';
frmEdgeCapture.Repaint;
Mappa:=NonMaxSuppression(Mappa);
SetImage(Bordi.Canvas, Mappa);
Bordi.Picture.SaveToFile('c:\NonMax.bmp');
StatusBar.Panels[0].Text := 'Definisco i bordi...';
frmEdgeCapture.Repaint;
Mappa:=Threshold(Mappa,seLo.Value,seHi.Value);
SetImage(Bordi.Canvas, Mappa);
Bordi.Picture.SaveToFile('c:\Threshold.bmp');
StatusBar.Panels[0].Text := 'Trovo la palla...';
frmEdgeCapture.Repaint;
trovato:=CentroPalla(Mappa,x0,y0,r0,percentuale);
Le funzioni che durano una vita sono Mappa:=Smooth(Mappa),
Mappa:=Gradiente(Mappa), Mappa:=NonMaxSuppression(Mappa) e
trovato:=CentroPalla(Mappa,x0,y0,r0,percentuale).
Lavorano tutte su una matrice tranne l'ultima fnzione che non modifica la
matrice ma mi da un booleano che mi dice se ha trovato la palla
nell'immagine e le coordinate di dove sta con la percentuale di esattezza
del risultato
Io sono arrivato qua, mo ditemi come come incapsulare ste 4 funzioni in dei
thread senza fare casini!


 in dei thread senza fare casini!
Questo è un thread che ridimensiona un'immagine:
unit Unit2;
interface
uses
  Windows, Classes, Graphics, ExtCtrls, SysUtils;
type
  TImageResizer = class(TThread)
  private
    { Private declarations }
    FSource: TBitmap;
    FDest: TBitmap;
    FImage: TImage;
    FSizeRatio: Single;
  protected
    procedure Execute; override;
    procedure UpdateImage;
  public
    procedure AfterConstruction; override;
    destructor Destroy; override;
    procedure SetOutputImage(const Img: TImage);
    procedure SetSourceBitmap(const Source: TBitmap);
    procedure SetSizeRatio(const SizeRatio: Single);
  end;
implementation
uses Unit1;
{ Important: Methods and properties of objects in visual components can only
be
  used in a method called using Synchronize, for example,
      Synchronize(UpdateCaption);
  and UpdateCaption could look like,
    procedure TImageResizer.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }
{ TImageResizer }
procedure TImageResizer.AfterConstruction;
begin
  inherited;
  FSource := nil;
  FImage := nil;
  FSizeRatio := 1;
  FDest := TBitmap.Create;
end;
destructor TImageResizer.Destroy;
begin
  FDest.Free;
  inherited;
end;
procedure TImageResizer.Execute;
var
  x, y: integer;
begin
  { Place thread code here }
  FreeOnTerminate := True;
  if (FSource=nil) or (FImage=nil) then
    raise Exception.Create('TImageResizer.Execute: Not enough parameters');
  // elaborazione dell'immagine
  FDest.Width := Trunc(FSource.Width * FSizeRatio);
  FDest.Height := Trunc(FSource.Height * FSizeRatio);
  FDest.Canvas.StretchDraw(Rect(0, 0, FDest.Width, FDest.Height), FSource);
  // ho finito, aggiorno l'image.
  Synchronize(UpdateImage);
end;
procedure TImageResizer.SetSourceBitmap(const Source: TBitmap);
begin
  FSource := Source;
  FDest.PixelFormat := FSource.PixelFormat;
end;
procedure TImageResizer.SetOutputImage(const Img: TImage);
begin
  FImage:= Img;
end;
procedure TImageResizer.UpdateImage;
begin
  FImage.Picture.Assign(FDest);
end;
procedure TImageResizer.SetSizeRatio(const SizeRatio: Single);
begin
  if SizeRatio<=0 then
    raise Exception.Create('TImageResizer.SetSizeRatio: Value
'+FormatFloat('#,##.##', SizeRatio)+' is not valid.');
  FSizeRatio := SizeRatio;
end;
end.
esempio d'uso:
  with TImageResizer.Create(True) do begin
    SetSourceBitmap(Image1.Picture.Bitmap);
    SetOutputImage(Image1);
    SetSizeRatio(1/2);
    Resume;
  end;
HTH,


Andrea M wrote:
<SNIP>
PS: ovviamente qua si suppone che nient'altro modifichi la bitmap originaria
durante l'operazione. Se non ti puoi permettere quest'ipotesi invece di
assegnare il riferimento (in SetSourceBitmap) puoi fare una copia della bmp
(istanzia FSource nell'AfterConstruction e usa Assign in SetSourceBitmap).
Ciao :-)


Mo vado al mare e torno tra una settimana
Proverò e vi farò sapere
Grazie mille per l'interessamento