Einzelnen Beitrag anzeigen

Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#12

AW: Multithreading lastet nur 1 Kern aus

  Alt 10. Feb 2012, 13: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.
  Mit Zitat antworten Zitat