TBitmap 32Bit erzwingen

Rund um die LCL und andere Komponenten
Antworten
Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

TBitmap 32Bit erzwingen

Beitrag von Mathias »

Unter Linux wird mit folgendem Code eine 32Bit Bitmap erzeugt, auch wen ich die Zeilen PixelFormat und Clear weg lasse.

Unter Windows wird ein 24Bit bitmap erzeugt, auch mit den Zeilen PixelFormat und Clear.

Gibt es eine Möglichkeit, das auch unter Windows ein 32Bit Bitmap erzeugt wird ?


Code: Alles auswählen

function CreateBitmap: TBitmap;
begin
  Result := TBitmap.Create;
  with
    Result do
  begin
    PixelFormat := pf32bit;
    Clear;
    Width := 16;
    Height := 16;
    with Canvas do
    begin
      Pen.Color := clWhite;
      Brush.Color := clWhite;
      Rectangle(0, 0, Result.Width, Result.Height);
      Pen.Color := clBlack;
      Line(0, 0, Result.Width, Result.Height);
    end;
  end;
end;   


Der umgekehrte Weg, ein 24Bit Bitmap unter Linux zu erzwingen geht auch nicht.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: TBitmap 32Bit erzwingen

Beitrag von Michl »

Mathias hat geschrieben:Gibt es eine Möglichkeit, das auch unter Windows ein 32Bit Bitmap erzeugt wird ?
Habe es jetzt mal probiert. Bei mir geht das unter Windows.

Müsstest einfach das "Clear" weglassen. Schaust du mal in die Methode von Clear, siehst du auch warum:

Code: Alles auswählen

procedure TCustomBitmap.Clear;
begin
  FPixelFormat := pfDevice;
  inherited Clear;
end;

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: TBitmap 32Bit erzwingen

Beitrag von Mathias »

Habe es probiert ich habe unter Windows somit 32 Bit, aber so wie es scheint ist die Bitmap transparent.
Irgendwie müsste man da noch den Alpha-Kanal mit $FF füllen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: TBitmap 32Bit erzwingen

Beitrag von Michl »

Mathias hat geschrieben:Irgendwie müsste man da noch den Alpha-Kanal mit $FF füllen.
Eben probiert, das könntest du danach z.B. so machen:

Code: Alles auswählen

procedure AddAlpha(aBitmap: TBitmap; Alpha: Byte);
type
  TColor32 = packed record
    case Integer of
      0: (B, G, R, A: Byte);
      1: (BGRA: UInt32);
    end;
  TColor32Array = array[0..0] of TColor32;
  PColor32Array = ^TColor32Array;
var
  x, y: Integer;
  Line: PColor32Array;
begin
  for y := 0 to aBitmap.Height - 1 do
  begin
    Line := aBitmap.ScanLine[y];
    for x := 0 to aBitmap.Width - 1 do
      Line^[x].A := Alpha;
  end;
end;

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: TBitmap 32Bit erzwingen

Beitrag von Mathias »

Irgendwie werde ich da nicht schlau.

Wen ich bei RawImage.Description gucke, gibt es die Werte BitsPerPixel, RedPrec, RedShift, etc.

Mit folgendem Code:

Code: Alles auswählen

function CreateBitmap: TBitmap;
begin
  Result := TBitmap.Create;
 
  with Result do begin
    PixelFormat := pf32bit;
    Width := 16;
    Height := 16;
 
    AddAlpha(Result, $FF);
 
    with Canvas do begin
      Pen.Color := clWhite;
     ...
habe ich unter Linux, folgende Ausgabe:

Code: Alles auswählen

  BitsPerPixel:32
  RedPrec:     8
  RedShift:    0
 
  GreenPrec:   8
  GreenShift:  8
 
  BluePrec:    8
  BlueShift:   16
 
  AlphaPrec:   8
  AlphaShift:  24

Lasse ich die Zeile mit PixelFormat := pf32bit; weg, dann kommt folgendes:

Code: Alles auswählen

  BitsPerPixel:32
  RedPrec:     8
  RedShift:    16
 
  GreenPrec:   8
  GreenShift:  8
 
  BluePrec:    8
  BlueShift:   0
 
  AlphaPrec:   0
  AlphaShift:  0

Aus RGB wird BGR und AlphaPrec ist weg.

Mache ich PixelFormat := pf24bit; dann habe ich bei BitsPerPixel komischerweise immer noch 32.

Unter Windows reagiert alles etwas anders. da geht nicht mal das obige AddAlpha.

So wie es mir scheint, hat TBitmap etwas Mühe mit der Platformübergreifbarkeit.
Oder verstehe ich da etwas falsch ?


Da gibt es noch die Befehle RawImage.Description.Init_BPPxxxxx(16,16)
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: TBitmap 32Bit erzwingen

Beitrag von Michl »

Nimm doch einfach fpImage, LazIntfImage, BGRABitmap oder OpBitmap, wie schon mehrfach in den anderen Threads geschrieben. Das Bitmap unterstützt generell schon 32bit, ein TBitmap.Canvas ist allerdings plattformabhängig.

[Edit]Ich vergaß:

AddAlpha soll danach aufgerufen werden (wie oben geschrieben)!

Also z.B. so:

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
var
  aBitmap: TBitmap;
begin
  aBitmap := CreateBitmap;
  AddAlpha(aBitmap, $FF);
  aBitmap.SaveToFile('C:\01\TestMitAlpha.bmp');
  aBitmap.Free;
end

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: TBitmap 32Bit erzwingen

Beitrag von Mathias »

AddAlpha soll danach aufgerufen werden (wie oben geschrieben)!


Egal, wie ich es mache, unter Linux ist es RGBA und unter Windows BGRA.

Nimm doch einfach fpImage, LazIntfImage, BGRABitmap oder OpBitmap,

Ich wollte nur in der schnelle eine Schraffur für OpenGL erzeugen, welche unter Windows und Linux läuft, und die gleichen Parameter in glTexImage2D
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten