Erst mal vielen Dank an Euch fürs mit überlegen, ich finde es echt spannend, hier die anderen Ansätze mal zu sehen. Jede der zuletzt genannten Varianten war immer ein weniger schneller als die Ausgangsfunktion.
Ich habe jetzt einfach mal bei ImageEn nachgesehen, die ich hier lizenziert habe, wie die das machen. Da ist das Bild zwar auch geringfügig unterschiedlich als meine Ausgangsfunktion, aber vielleicht war meine ja auch nicht korrekt.
Jedenfalls in Anlehnung an die ImageEn-Lösung kann man das hier so machen ist das ist dann mit 71 MS die bislang schnellste Lösung und toppt sogar die Parallel-Lösung. Da ist dann irgendwann anscheinend der Zeitbedarf für das Management des Threading größer, als der Zeitgewinn durch den Einsatz mehrerer Kerne. Insofern muss man sich genau ansehen, wann man die Parallelisierung einsetzt. Besserer Code geht also meistens doch noch vor Parallel-Bearbeitung. Wahrscheinlich lohnt sich die Parallelisierung eher bei Prozessen, die eh schon etwas länger dauern.
Delphi-Quellcode:
// Setz vorraus, dass die Bitmaps die gleiche Größe haben!!!
procedure Draw32BitToBitmap(const BitOben: TBitmap; BitUnten: TBitmap);
var
h,w,i: Integer;
RGBA_Unten, RGBA_Oben: pRGBALine;
begin
For h := 0 to BitUnten.Height-1 do begin
RGBA_Unten := BitUnten.ScanLine[h];
RGBA_Oben := BitOben.ScanLine[h];
For w:= 0 to BitUnten.Width-1 do begin
if RGBA_Oben^[w].rgbReserved = 0 then begin
// unten bleibt
end else begin
(* Das war die Ausgangslösung
i := Round (RGBA_Unten^[w].rgbBlue - ((RGBA_Unten^[w].rgbBlue - RGBA_Oben^[w].rgbBlue) / 255 * RGBA_Oben^[w].rgbReserved));
if i < 0 then RGBA_Unten^[w].rgbBlue := 0 else if i > 255 then RGBA_Unten^[w].rgbBlue := 255 else RGBA_Unten^[w].rgbBlue := i;
i := Round (RGBA_Unten^[w].rgbGreen - ((RGBA_Unten^[w].rgbGreen - RGBA_Oben^[w].rgbGreen) / 255 * RGBA_Oben^[w].rgbReserved));
if i < 0 then RGBA_Unten^[w].rgbGreen := 0 else if i > 255 then RGBA_Unten^[w].rgbGreen := 255 else RGBA_Unten^[w].rgbGreen := i;
i := Round (RGBA_Unten^[w].rgbRed - ((RGBA_Unten^[w].rgbRed - RGBA_Oben^[w].rgbRed) / 255 * RGBA_Oben^[w].rgbReserved));
if i < 0 then RGBA_Unten^[w].rgbRed := 0 else if i > 255 then RGBA_Unten^[w].rgbRed := 255 else RGBA_Unten^[w].rgbRed := i;
*)
RGBA_Unten^[w].rgbred := (RGBA_Oben^[w].rgbReserved * (RGBA_Oben^[w].rgbred - RGBA_Unten^[w].rgbred) shr 8 + RGBA_Unten^[w].rgbred);
RGBA_Unten^[w].rgbGreen := (RGBA_Oben^[w].rgbReserved * (RGBA_Oben^[w].rgbgreen - RGBA_Unten^[w].rgbGreen) shr 8 + RGBA_Unten^[w].rgbGreen);
RGBA_Unten^[w].rgbBlue := (RGBA_Oben^[w].rgbReserved * (RGBA_Oben^[w].rgbBlue - RGBA_Unten^[w].rgbBlue) shr 8 + RGBA_Unten^[w].rgbBlue);
RGBA_Unten^[w].rgbReserved := 255;
end;
end;
end;
end;