Thema: Delphi Lese PByte in TBitmap

Einzelnen Beitrag anzeigen

itblumi

Registriert seit: 28. Mär 2009
73 Beiträge
 
Delphi XE6 Professional
 
#5

AW: Lese PByte in TBitmap

  Alt 22. Okt 2022, 20:26
Echt einfach geht das wenn Du Dir eine TBitmap mit 32 oder 24 bit erstellst und über entsprechende pointer alle Scanlines[] abarbeitest. Dabei kannst Du auch eine RGB BGR Umwandlung machen, sofern erforderlich.
Nach dem jziersch geschrieben hatte das dies "echt einfach geht", hat mich der Eifer gepackt und ich habe das Ganze dann mal "fix" umgesetzt.
Mir ist dann auch noch aufgefallen das ich von der externen Komponente den Raster mit geliefert bekomme und habe diesen dann genutzt um die
Bytes dementsprechend in das Bitmap zu kopieren. Im Endeffekt war der Raster in diesem Fall um 4 Bytes länger als der errechnet Wert von
BytesPerScanline und dieser hat im Bild die Verschiebung verursacht.

Hier ist das Ergebnis:
Code:
var
  ABmpInfo: BITMAPINFO;
  DestBytes: PByte;
  i, AByteWidth, Row: Integer;
begin
  if (Assigned(PImage)) then
  begin
    // initialize the size of the image
    SetSize(FBmpInfoHeader.biWidth, FBmpInfoHeader.biHeight);
    // only use the raster when the calculated ByteWidth is different
    if (FGS_Raster <> FByteWidth) then
    begin
      // get the PixelFormat from the BITMAPINFOHEADER
      PixelFormat := GetPixelFormatFromBMIH;
      // we have to use the raster to get the correct length of a line
      AByteWidth := FGS_Raster;
      for i := 0 to FBmpInfoHeader.biHeight - 1 do
      begin
        // get the pointer to the image data of the bitmap line
        DestBytes := Scanline[i];
        // In Windows we will paint the image bottom first, so we need to start
        // at the last row and end at the first row
        Row := FBmpInfoHeader.biHeight - 1 - i;
        // copy the image memory to the bitmap memory
        CopyMemory(DestBytes, PImage + AByteWidth * Row, AByteWidth);
        // convert if needed
        //TODO: implement convert functions
      end;
    end else
    begin
      ABmpInfo.bmiHeader := FBmpInfoHeader;
      FGS_ImageDataLoaded := (SetDIBits(0, Handle, 0, Abs(FBmpInfoHeader.biHeight),
                                        PImage, ABmpInfo, DIB_RGB_COLORS)) > 0;
    end;
  end;
end;
Für meinen Fall bekomme ich jetzt auch das richtige Ergebnis. Es gibt aber einen Punkt in dem ich mir nicht sicher bin und dies betrifft
das TBitmap.PixelFormat dieses ermittele ich über den biBitCount der zuvor gesetzt wurden ist.

Hier noch die Funktion um das PixelFormat zu ermitteln
Code:
function TGS_Image.GetPixelFormatFromBMIH: TPixelFormat;
begin
  case (FBmpInfoHeader.biBitCount) of
    1: Result := pf1bit;
    4: Result := pf4bit;
    8: Result := pf8bit;
    15: Result := pf15bit;
    16: Result := pf16bit;
    24: Result := pf24bit;
    32: Result := pf32bit;
    else
      Result := pfDevice;
  end;
end;
Jan
Ein neuer Tag bringt so einiges mit sich. Was auch immer es ist, es bleibt ein kleines Abenteuer.

Geändert von itblumi (22. Okt 2022 um 20:32 Uhr)
  Mit Zitat antworten Zitat