Autor Beitrag
GuaAck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 378
Erhaltene Danke: 32

Windows 8.1
Delphi 10.4 Comm. Edition
BeitragVerfasst: So 30.11.14 21:09 
Liebe Experten,

ich mache eine rechenintensive Bildanalyse. Das Bild liegt als TBitmap vor. Die Farbe eines Pixels hole ich mit Bitmap.canvas.pixels[x,y]. Nun mein Problem:

Ich will die Arbeit in einem eignen Thread (TTHREAD) machen und habe sie in der EXECUTE-Methode untergbracht. Das Bitmap ist lokal in der Klasse erklärt, wird dort im CREATE erzeugt und erst bei FREE wieder gelöscht.

Das Bild wird aber nur zum Teil bearbeitet, ab einem gewissen Zeitpunkt gibt Bitmap.canvas.pixels[x,y] immer den Wert -1. Laut Hilfe zeigt das, dass der Punkt außerhalb des ClipRect liegt. Stimmt auch, aus irgend einem Grund ist das ClipRect auf ((0,0),(1,1)) gesetzt. Zu Beginn der Baerbeitung ist es korrekt auf Bildbreite und -höhe gesetzt.

Lasse ich das EXECUTE nicht per RESUME starten sondern rufe es von Hautpthread einfach als Procedure auf, dann geht alles bestens.

Hat jemand eine Idee, wer bei einer lokalen Bitmap das ClipRect ändern könnte? Ich selbst kann es nicht ändern, es ist ja eine nur lesbare Eigenschaft.

Beste Grüße
GuaAck
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19321
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 30.11.14 21:41 
TBitmap im Thread ist keine so gute Idee. Mit Canvas.Lock davor bzw. danach Canvas.Unlock sollte es aber gehen.

Nebenbei:
Rechenintensiv ist der Zugriff auf Pixels in der Tat... Wenn du das ganze auf ScanLine umstellst, ist es evtl. schon so schnell, dass du gar keinen Thread mehr brauchst. Da hatte ich schon 100 fache Beschleunigung...

Für diesen Beitrag haben gedankt: GuaAck
GuaAck Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 378
Erhaltene Danke: 32

Windows 8.1
Delphi 10.4 Comm. Edition
BeitragVerfasst: So 30.11.14 23:28 
Hallo Jaenicke,

danke, mit Lock/unlock geht es. Bei vier Threads sehe ich mit dem Windows Resourcen-Monitor, dass zwar vier CPUs arbeiten, aber zusammen nur zu 40 %. TBitmap scheint also gemeinsame Resourcen zu nutzen.

Das mit Pixels[x,y] und scanlines probiere ich, in einer anderen Anwednung kann ich deine Erfahrung voll bestätigen. Da ich jedoch nicht zeilenweise auf die Pixels zugreife schien mir Pixels praktischer.

Gruß GuaAck
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: So 30.11.14 23:39 
Ein Blick in die Rückgabewerte von Scanlines wird die schnell die Augen öffnen ;)

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19321
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 01.12.14 10:30 
Es geht ggf. sogar schneller die einzelnen Pointer der Zeilen in ein eigenes Array zu schreiben und auf alles wie auf ein Array zuzugreifen.
Der Grund ist, dass Pixels für jedes einzelne Pixel die API Funktion GetPixel aufruft... das geht natürlich nicht so schnell wie ein einfaches Berechnen der Speicherposition eines Arraywerts.