AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher?
Thema durchsuchen
Ansicht
Themen-Optionen

Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher?

Ein Thema von axelf98 · begonnen am 30. Jun 2005 · letzter Beitrag vom 4. Jul 2005
Antwort Antwort
Seite 1 von 2  1 2      
axelf98

Registriert seit: 27. Aug 2003
Ort: Ennepetal
440 Beiträge
 
Delphi 2005 Personal
 
#1

Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher?

  Alt 30. Jun 2005, 23:35
Hallo!
Ich programmiere grad ein FotoShow-Programm, das mit Hilfe eine Threads die Thumbnails erstellt. Dabei kann man in einer Liste scrollen, und sehen, wo das Programm grad ist mit den Thumbs. Das klappt auch ganz gut, nur bei 100 Bildern sind sporadisch 1-2 dabei die er nicht anzeigt, weiß bleiben.
Als Routine nehme ich Canvas.StretchDraw(..). Auch StretchBlt zeigt neben reduzierter Farbtiefe dieses Verhalten. Nehme ich dagegen Canvas.Draw, sind alle Bilder da und zeigen einen Ausschnitt vom Bild (Sinnigerweise nicht das ganze).

Mir scheint, dass die Stretch-Befehle nicht Thread-sicher sind. Habt ihr Ideen?
  Mit Zitat antworten Zitat
Benutzerbild von Sanchez
Sanchez

Registriert seit: 24. Apr 2003
Ort: Neumarkt Stmk
892 Beiträge
 
Delphi XE6 Enterprise
 
#2

Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher

  Alt 1. Jul 2005, 08:26
Hallo,
Eine brauchbare Qualität erreichst du mit StretchBlt indem du vorher den StretchBlt-Modus setzt:
Delphi-Quellcode:
  SetStretchBltMode(Canvas.Handle, STRETCH_HALFTONE);
  SetBrushOrgEx(Canvas.Handle, 0, 0, nil);
Zur Threadsicherheit dieser Funktionen kann ich dir leider nichts sagen.
Könnte evtl. nicht eher das Problem sein, dass deine Threads irgendwas auf die Oberfläche pinseln?

grüße, daniel
Daniel
Testen ist feige!
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher

  Alt 1. Jul 2005, 08:40
Threadsicher wirst du das ganze selbst machen müssen. Also die Thumbs im Thread erzeugen und dann um das Thumb anzuzeigen (die Anzeigekomponente gehört ja dann zum Hauptthread) musst du wohl mit Syncronize arbeiten.
Also Thumb in Thread erzeugen -> Bild syncron mit Hauptthread zuweisen
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
axelf98

Registriert seit: 27. Aug 2003
Ort: Ennepetal
440 Beiträge
 
Delphi 2005 Personal
 
#4

Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher

  Alt 1. Jul 2005, 12:14
Zitat von SirThornberry:
Also Thumb in Thread erzeugen -> Bild syncron mit Hauptthread zuweisen
Ich werds versuchen.. Mal schaun, was daraus wird.
Die Qualität ist mit StretchBlt und
Delphi-Quellcode:
SetStretchBltMode(Canvas.Handle, STRETCH_HALFTONE);
SetBrushOrgEx(Canvas.Handle, 0, 0, nil);
wesentlich besser als mit StretchDraw!
  Mit Zitat antworten Zitat
axelf98

Registriert seit: 27. Aug 2003
Ort: Ennepetal
440 Beiträge
 
Delphi 2005 Personal
 
#5

Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher

  Alt 3. Jul 2005, 18:41
Hallo nochmal! Leider konnte ich keine Möglichkeit finden, die beiden genannten Prozeduren threadsicher zu machen. Selbst die Kapselung in dem Thread, der Schutz vor Zugriffen durch ein extra-Array (erst erstellen, dann ins Hauptprogramm kopieren) hat nichts gebracht. Mir ist aufgefallen dass StretchBlt hier mehr Aussetzer hat als StretchDraw.
Ich suche nach einer alternativen Prozedur oder Funktion, die Bilder verkleinert zeichen kann. Ich überlege grade, die G32-Lib zu benutzen, möchte aber eigentlich auf Fremdkomponenten verzichten.

Wer weiß Rat?
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#6

Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher

  Alt 3. Jul 2005, 18:56
@axelf98: Wie hast du das ganze umgesetzt? Arbeitest du mit der Delphiklasse TThread?
auf folgende Art und weise sollte es eigentlich ohne Probleme möglich sein
Delphi-Quellcode:
type
  TMyThead = class(TThread)
  private
    procedure MethodForSync;
  protected
    procedure Execute; override;
  end;

[...]
procedure TMyThead.MethodForSync;
begin
  //Dem TImage aus dem Hauptform das ganze zuweisen
  DeinHauptForm.Image1.Picture.Bitmap.Assign(ThumbPicAusThread)
end;

procedure TMyThead.Execute;
begin
  //Thumb zerugen
  Synchronize(MethodForSync);
end;
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
axelf98

Registriert seit: 27. Aug 2003
Ort: Ennepetal
440 Beiträge
 
Delphi 2005 Personal
 
#7

Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher

  Alt 3. Jul 2005, 19:12
Zitat von SirThornberry:
@axelf98: Wie hast du das ganze umgesetzt? Arbeitest du mit der Delphiklasse TThread?
Ja genau, meine Record:

Delphi-Quellcode:
Type TFoto = record // Was alles drin sein kann
 FileScr: String;
 Vorschau: TBitmap;
end;
Type pTFoto = ^TFoto; // Pointer für den Record
Mein Thread:
Delphi-Quellcode:
type
  Vorschaubildererstellen = class(TThread)

  public
    constructor INIT(Daten: TFotoShow; Gaug: TGauge; Gri: TStringgrid; Pane: TPanel);
  private
    { Private-Deklarationen }
    mFotos: TFotoShow; // Für den Daten Zugriff aufs Form Übergabe der Pointer
    Gauge: TGauge;
    Grid: TStringgrid;
    Panel: TPanel;
  protected
    procedure Vorschauerstelleneinzeln(Nr,Gr: integer; Fot: pTFoto);
    procedure Execute; override;
  end;

implementation
uses main;

constructor Vorschaubildererstellen.INIT(Daten: TFotoShow; Gaug: TGauge; Gri: TStringgrid; Pane: TPanel);
begin
 mFotos := Daten;
 Gauge := Gaug;
 Grid := Gri;
 Panel := Pane;
 inherited create(false);
end;

procedure Vorschaubildererstellen.Execute; // Thread
var i: integer;
  tmp : pTFoto;
begin

 for i := 0 to mFotos.AnzahlFotos-1 do
 begin
  tmp := mFotos.Elemente.Items[i];
  if tmp^.Vorschau = nil then
  begin
  Vorschauerstelleneinzeln(i,mFotos.VorschauGr,tmp);
  end;
 end;
end;

procedure Vorschaubildererstellen.Vorschauerstelleneinzeln(Nr,Gr: integer; Fot: pTFoto);
var LadImage: Timage;
    Verh: Double;
    hoehe, weite,x: integer;
    Extention: String;
    LadBitmap: TBitmap;
    jpg: TJPEGImage;
    MegaP: Real;
    Verk: TBildverkleiner;
begin

 try
 Extention := Ansilowercase(Extractfileext(Fot^.FileScr));

  if Fot^.Vorschau = nil then
  Fot^.Vorschau := TBitmap.Create;

 if (Extention = '.jpg') OR (Extention = '.jpeg') then
 begin /// JPGS schnell!!!! ---------------------------------
  LadBitmap := TBitmap.Create;
  jpg := TJPEGImage.create;
  jpg.LoadFromFile(Fot^.FileScr);

   MegaP := (JPG.Width*JPG.Height)/1000000;
   if MegaP > 1 then
    JPG.Scale := jsEighth ELSE // schnell!!
   if MegaP > 0.3 then
    JPG.Scale := jshalf ELSE
    JPG.Scale := jsFullSize;

  LadBitmap.Assign(jpg);

 if (LadBitmap.Width > 0) AND (LadBitmap.Height > 0)then
  begin
   Verh := LadBitmap.Width/LadBitmap.Height;
   Fot^.Vorschau.Width := Gr;
    Fot^.Vorschau.Height := Gr;
   if Verh >= 1 then
   begin
   hoehe := Round(Gr/Verh);
   x := round((Gr-hoehe)/2);
  Fot^.Vorschau.Canvas.StretchDraw(Rect(0,x,Gr,hoehe+x),LadBitmap); // HIER wird gemalt
   end ELSE
   begin
   weite := Round(Gr*Verh);
   x := round((Gr-weite)/2);
   Fot^.Vorschau.Canvas.StretchDraw(Rect(x,0,weite+x,gr),LadBitmap); // HIER wird gemalt
   end;
   end;
  jpg.Free;
  LadBitmap.Free;
 end ELSE
 begin

 /// BMPS oder anderes
  
  end ELSE
  begin
   Fot^.Vorschau := nil;
  end;
  LadImage.Free;
 end;
 except
    Fot^.Vorschau := nil;
  end;
 end;
Ich schreibe nochmals, dass jede andere Prozedur, sei es Canvas.Draw(..), Canvas.Rectangle oder ähnliches anstelle des StretchDraw wunderbar funktioniert und jedes Mal gezeichnet wird!
  Mit Zitat antworten Zitat
Benutzerbild von BlackJack
BlackJack

Registriert seit: 2. Jul 2005
Ort: Coesfeld
246 Beiträge
 
Delphi 2005 Personal
 
#8

Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher

  Alt 3. Jul 2005, 21:43
die stellen mit "//HIER wird gemalt" müsstest du in eine extra procedure packen, und diese dann mit
Code:
Syncronize(Proc);
aufrufen.
informier dich ansonsten nochmal in der Hlife über die funktionsweise von TThread.Syncronize().
See my shadow changing, stretching up and over me.
Soften this old armor. Hoping I can clear the way
By stepping through my shadow, coming out the other side.
Step into the shadow. Forty six and two are just ahead of me.
  Mit Zitat antworten Zitat
axelf98

Registriert seit: 27. Aug 2003
Ort: Ennepetal
440 Beiträge
 
Delphi 2005 Personal
 
#9

Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher

  Alt 4. Jul 2005, 00:57
Zitat von BlackJack:
die stellen mit "//HIER wird gemalt" müsstest du in eine extra procedure packen, und diese dann mit
Code:
Syncronize(Proc);
aufrufen.
Die Lösung ist zwar programmiertechnisch (nicht ganz OOP) etwas umständlich, aber die funtioniert! DANKE
  Mit Zitat antworten Zitat
Gandalfus

Registriert seit: 19. Apr 2003
407 Beiträge
 
Delphi 2006 Professional
 
#10

Re: Bildändern (StretchDraw, StretchBlt) nicht Thread-sicher

  Alt 4. Jul 2005, 02:11
Delphi-Quellcode:
canvas.lock
canvas.unlock
Besucht doch mal meine Homepage
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:41 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz