Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
FreePascal / Lazarus
|
AW: Multithreading lastet nur 1 Kern aus
10. Feb 2012, 14:51
Kann ich jetzt auf Anhieb auch nicht erkennen. Teste doch erst mal, ob es an der Zuweisung oder an der Berechnung liegt, indem du R, B und G jeweils $FF (255) zuweist. Das Bild sollte dann ja weiß sein. Wenn es das nicht ist, weißt du zumindest, wo du suchen musst.
Mal ganz allgemein ein paar Dinge:
Delphi-Quellcode:
// 1. Das T sollte aus dem Funktionsnamen entfernt werden, da die Funktion sonst
// .. für einen Typen halten könnte. Außerdem gibt es keinen Grund "To" als "2"
// .. abzukürzen.
// 2. Ich würde statt "var" "out" verwenden, damit klar ist, dass diese Parameter
// .. ausschließlich der Ausgabe und nicht der Eingabe dienen.
procedure TColor2RGB(Color: TColor; VAR R, G, B: Byte);
begin
if Color SHR 24 = $FF then Color:=GetSysColor(Color AND $FF)
else if Color SHR 24 > $02 then Color := 0;
// Funktioniert zwar, aus Gründen der Verständlichkeit würde ich aber
// and $FF ans Ende dieser Zeilen anfügen, damit klar ist, dass
// Der Wert auf 0..255 beschränkt ist.
R := Color;
G := (Color shr 8);
B := (Color shr 16);
end;
function ArrayofColorToBitmap(AoC: ColorArray):TBitmap;
type
// 1. Ein Array mit einem Start-Index von 1 ist unüblich.
// .. Nimm stattdessen besser [0..2]
// 2. Bei solchen Strukturen, wo es sehr darauf ankommt, dass
// .. die Daten in einer bestimmten Anordnung im Speicher liegen
// .. immer packed array bzw. packed record statt einem normalen
// .. array/record verwenden.
// .. Sonst kannst du nie sicher sein, dass die Bytes auch wirklich
// .. direkt hintereinander liegen, ohne irgendwelche Lücken dazwischen.
// 3. Es gibt bereits einen Datentyp der hierfür geeignet ist, er heißt
// .. TRGBTriple.
// 4. Typen beginnen per Konvention mit dem Präfix T. Der Typ sollte also
// .. TPixArray heißen, und nicht PixArray.
PixArray = Array [1..3] of Byte;
VAR i,j:integer; p: ^PixArray; R,G,B: Byte;
begin
result:=TBitmap.Create;
// Effizienter ist pf32Bit, weil der Speicher auf 32 Bit aligned ist.
// D.h. 32 Bit können mit einem Lesebefehl eingelesen werden, bei
// 24 Bit sind ggf. 2 Lese-Befehle nötig.
// Ein weiterer Vorteil ist, dass nicht mehr unbedingt einen eigenen
// Datentyp wie PixArray für die Verarbeitung brauchst, sondern einfach
// einen Integer/Cardinal oder TColor nehmen kannst, die ebenfalls
// 32 Bit breit sind. Alternativ kannst du TRGBQuad verwenden, womit
// du komfortabel auf die einzelnen Bytes R, G, B und A zugreifen kannst.
// Wenn du weiterhin dein PixArray verwendest, musst du es natürlich
// auf 4 Elemente erweitern.
result.PixelFormat := pf24Bit;
result.Width:=Length(AoC);
result.Height:=Length(AoC[0]);
for i := 0 to Length(AoC[0])-1 do
begin
p:= result.ScanLine[i];
for j := 0 to Length(AoC)-1 do
begin
TColor2RGB(Aoc[j,i], R, G, B);
p^[1]:=B; //<-------- die Kanäle sind schon vertauscht
p^[2]:=G;
p^[3]:=R;
Inc(p);
end;
end;
end;
Und grundsätzlich könntest du dir die ganze Konvertiererei auch sparen, wenn du direkt mit der Scanline arbeiten würdest.
|
|
Zitat
|