TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Rund um die LCL und andere Komponenten
MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von MmVisual »

Hallo,

Ich habe keine Bildchen, die werden in einer TImageList gehalten. Zur Laufzeit erzeuge ich ein großes TBitmap mit mehreren "Stern" Bitmaps um Ratings darzustellen.
Dieser Code funktioniert unter Windows:

Code: Alles auswählen

      imges.GetBitmap(42, bmrt);
      For i := 11 Downto 2 Do // rote Sterne
      Begin
        bm := TBitmap.Create;
        bm.Assign(bmrt); // Erst mal zuweisen damit all Bitmap Eigenschaften gleich sind
        bm.Width := i * bmrt.Width;
        bm.Height := bmrt.Height;
        k := 0;
        while (k < (bm.Width - 2)) Do
        Begin
          bm.Canvas.Draw(k, 0, bmrt); // Stern Rot
          Inc(k, bmrt.Width);
        end;
        lstRating.Add(Pointer(bm));
      end;
      lstRating.Add(Pointer(bmrt)); // ein roter Stern
 
Unter Linux bleibt das Bild leer. :cry:

Wenn ich die Zeile bm.Assign(...) weg lasse sondern nur die Bilder hinein zeichne, dann sind die Bildchen (Sterne) alle da, aber der Hintergrund wird schwarz :cry: :cry:

Mask / Transparent einstellen usw. ich bekomme es einfach nicht hin. Das Bitmap aus der TImageList hat pf32Bit, nach dem TBitmap.Create hat es nur pf24Bit. Sobald ich es auf pf32Bit setze wird unter Linux nichts mehr gezeigt.

Dargestellt wird das Bild so:
imgRating.Picture.Bitmap.Assign(TBitmap(lstRating));

Bei der Darstellung "ein roter Stern" wird das Bitmap gezeigt. Nur nicht das wenn mehrere Sterne in einem Bitmap zusammen kopiert sind.

Weiß jemand Rat was ich ändern könnte / muss?

Suse 12.3, "lazarus-1.1.40204-20130208.laz.x86_64.rpm", "fpc-2.6.0-0.laz.x86_64.rpm"

Vielen Dank im Voraus. Grüße Markus
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
theo
Beiträge: 10907
Registriert: Mo 11. Sep 2006, 19:01

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von theo »

Wenn du da eine Antwort möchtest, dann müsstest du ein compilierbares Projekt hochladen, welches das Problem in minimalem Kontext zeigt. Bilder inklusive.

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von MmVisual »

Mache ich heute Abend fertig.
EleLa - Elektronik Lagerverwaltung - www.elela.de

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von MmVisual »

Wie versprochen, hier das Demo.

Unter Windows funktioniert es, bei Linux wird ein leeren Bild gezeigt (bei 2 Sterne).
In der Radio-Group kann zwischen 1 und 2 Sterne umgeschaltet werden.
Dateianhänge
TestBild.zip
(139.65 KiB) 103-mal heruntergeladen
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
theo
Beiträge: 10907
Registriert: Mo 11. Sep 2006, 19:01

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von theo »


MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von MmVisual »

Nein, hatte ich nicht gelesen. Aber das .Transparent und .TransparentColor habe ich vorher schon mal gesetzt, ohne Erfolg:

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
Var k: Integer;
  bm, bmrt: TBitmap;
begin
  lstRating := TList.Create;
  bmrt := TBitmap.Create;
  imges.GetBitmap(42, bmrt);
  lstRating.Add(Pointer(bmrt)); // ein roter Stern
  Begin
    bm := TBitmap.Create;
    //bm.Assign(bmrt);
    bm.Width := 2 * bmrt.Width;
    bm.Height := bmrt.Height;
    k := 0;
    while (k < (bm.Width - 2)) Do
    Begin
      bm.Canvas.Draw(k, 0, bmrt); // Stern Rot
      Inc(k, bmrt.Width);
    end;
    bm.TransparentColor := bm.Canvas.Pixels[0,0];
    //bm.TransparentColor := bm.Canvas.Pixels[1,1];
    bm.Transparent := True;
    lstRating.Add(Pointer(bm));
  end;
end;  
Der Bildhintergrund bleibt schwarz.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
theo
Beiträge: 10907
Registriert: Mo 11. Sep 2006, 19:01

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von theo »

MmVisual hat geschrieben:Nein, hatte ich nicht gelesen.
Du hast es offenbar noch immer nicht gelesen, v.A. der Teil mit dem memstream. :wink:

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von MmVisual »

Wenn ich von Dir einen Tipp bekomme, dann lese ich den garantiert.
Wie kann ich mittels einem TMemStream ein Bildchen 16x16 Pixel aufdoppeln, so dass es 2x in einem neuen Bitmap 32x16Pixel drin ist?
Mit "imges.GetBitmap(42, bmrt);" bekomme ich so viele Bitmaps raus wie ich mag, daher brauche ich kein TMemStream um ein Bild zu kopieren.

Ich meine eher, das was ich will (Canvas.DrinMalenMitDraw) ist ein Bug unter Lazarus/Linux und ich müsste ein Bugreport schreiben?
EleLa - Elektronik Lagerverwaltung - www.elela.de

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von Scotty »

Mit Qt funktioniert es OOTB. Und wenn du vor oder hinter dem imgRating.Picture.Bitmap.Assign() ein Bitmap.SaveToFile() machst, dann kommt da auch die richtige Graphik raus.
Das eigentliche Problem ist das erste bm.Assign(bmrt) (wozu auch?). Kommentiere das raus und der Doppelstern wird angezeigt. Ich nehme an, dass durch das Assign() Parameter im Bitmap gesetzt werden, die mit der folgenden Änderung (width:=2*w) kollidieren. Vermutlich tief in den gtk2 Eingeweiden.

Soner
Beiträge: 734
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von Soner »

Die Zeile:
bm.Assign(bmrt);
erzeugt den Fehler wenn man es auskommentiert wird etwas gezeigt.
Außerdem finde ich das ganze nicht gelungen bzw. sauber programmiert. Wiese erstellst du ein Bitmappuffer (var bm) für ein Stern wenn du gleich von der Bilderliste (imges) zeichnen kannst? Schau nach TImageList.Draw.

Ich würde es so machen:

Code: Alles auswählen

 
procedure TForm1.FormCreate(Sender: TObject);
Var bmleer: TBitmap;
begin
  //leeres bild für manipulationen hinzufügen
  bmleer := TBitmap.Create;
  bmleer.Height:=imges.Height;
  bmleer.Width:=1;
  bmleer.Canvas.Clear;
  bmleer.Transparent:=true;
  imgRating.Picture.Bitmap.Assign(bmleer);
 
  //Vergiss nicht in Objektinspektor  imgRating: TImage; transparent zu machen!
end;
 
procedure TForm1.RadioGroup1Click2(Sender: TObject);
var i,x : integer;
begin
  if RadioGroup1.ItemIndex<0 then exit;
  imgRating.Picture.Bitmap.Width:=imges.Width*(RadioGroup1.ItemIndex+1);
  x:=0;
  for i:=0 to RadioGroup1.ItemIndex do begin
     imges.Draw(imgRating.Picture.Bitmap.Canvas, x, 0, 42);   
     inc(x,imges.Width);
  end;
end;
 
Wenn du Anzahl von Radioitems änderst wird es sogar automatisch gezeichnet.

Heinrich Wolf
Beiträge: 323
Registriert: Di 12. Apr 2011, 13:21
OS, Lazarus, FPC: WinXP + VMWare Player mit Fedora14, L 1.1, FPC 2.7.1
CPU-Target: 1core 1,8GHz 32Bit
Wohnort: Fürth
Kontaktdaten:

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von Heinrich Wolf »

Scotty hat geschrieben:Das eigentliche Problem ist das erste bm.Assign(bmrt) (wozu auch?). Kommentiere das raus und der Doppelstern wird angezeigt.
MmVisual hat geschrieben:Wenn ich die Zeile bm.Assign(...) weg lasse sondern nur die Bilder hinein zeichne, dann sind die Bildchen (Sterne) alle da, aber der Hintergrund wird schwarz :cry: :cry:

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von Scotty »

Heinrich Wolf hat geschrieben:
Scotty hat geschrieben:Das eigentliche Problem ist das erste bm.Assign(bmrt) (wozu auch?). Kommentiere das raus und der Doppelstern wird angezeigt.
MmVisual hat geschrieben:Wenn ich die Zeile bm.Assign(...) weg lasse sondern nur die Bilder hinein zeichne, dann sind die Bildchen (Sterne) alle da, aber der Hintergrund wird schwarz :cry: :cry:
Okay, du hast besser aufgepasst :mrgreen:. Das ist dann aber ein anderes Problem.

Heinrich Wolf
Beiträge: 323
Registriert: Di 12. Apr 2011, 13:21
OS, Lazarus, FPC: WinXP + VMWare Player mit Fedora14, L 1.1, FPC 2.7.1
CPU-Target: 1core 1,8GHz 32Bit
Wohnort: Fürth
Kontaktdaten:

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von Heinrich Wolf »

Soner hat geschrieben:Wiese erstellst du ein Bitmappuffer (var bm) für ein Stern wenn du gleich von der Bilderliste (imges) zeichnen kannst? Schau nach TImageList.Draw.

Ich würde es so machen:
MmVisual hat geschrieben:Aber das .Transparent und .TransparentColor habe ich vorher schon mal gesetzt, ohne Erfolg:
...
Der Bildhintergrund bleibt schwarz.

Benutzeravatar
theo
Beiträge: 10907
Registriert: Mo 11. Sep 2006, 19:01

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von theo »

Mach das bm.Assign(bmrt); weg und setze die Eigenschaft "Transparent" von imgRating auf true im Obj. Insp.

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: TBitmap.Canvas.Draw funktioniert unter Linux nicht???

Beitrag von MmVisual »

Vielen Dank für die Tipps. Tut leider dennoch nicht :cry:

Den Code habe ich nun so abgeändert:

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
Var k: Integer;
  bm, bmrt: TBitmap;
begin
  lstRating := TList.Create;
  bmrt := TBitmap.Create;
  imges.GetBitmap(42, bmrt);
  lstRating.Add(Pointer(bmrt)); // ein roter Stern
  Begin
    bm := TBitmap.Create;
    //bm.PixelFormat := pf32bit;
    //bm.Assign(bmrt);
    bm.Width := 2 * bmrt.Width;
    bm.Height := bmrt.Height;
    k := 0;
    while (k < (bm.Width - 2)) Do
    Begin
      imges.Draw(bm.Canvas, k, 0, 42);
      //bm.Canvas.Draw(k, 0, bmrt); // Stern Rot
      Inc(k, bmrt.Width);
    end;
    //bm.Transparent:=true;
    //bm.TransparentColor:=clBlack;
    lstRating.Add(Pointer(bm));
 
    // Zum Test direkt in TImage:
    imgRating.Picture.Bitmap.Width := 2 * bmrt.Width;
    imgRating.Picture.Bitmap.Height := bmrt.Height;
    k := 0;
    while (k < (imgRating.Picture.Bitmap.Width - 2)) Do
    Begin
      imges.Draw(imgRating.Picture.Bitmap.Canvas, k, 0, 42);
      Inc(k, bmrt.Width);
    end;
  end;
end;   
Die auskommentierten Zeilen jeweils zum Test. Auch wenn ich ein "imges.Draw()" direkt in das TImage "imgRating" ausführe, dann wird zwar das Bild gezeichnet aber der Hintergrund ist schwarz und nicht transparent.

Das TBitmap.Assign() sollte schon funktionieren, denn damit weiße ich nicht nur das Bild zu, sondern auch gleich mit alle anderen Parameter wie z.B. Pixelformat, Transparenz, Canvas.Font usw. Also mit Assign() erhalte ich eine exaktie 1:1 Kopie der gesamten Struktur TBitmap und nicht nur das Bitmap. Daher ist die Assign() Zuweisung enorm wichtig und erleichtert die Programmierung. (Mit Assign() habe ich schon vor 13 Jahren als ich mit Delphi anfing ganze Datenstrukturen kopiert.)

So sieht das ganze mit den Ratings unter Windows aus:
Bild1.png
Bild1.png (6.06 KiB) 2378 mal betrachtet
Anzeige der Sterne in der Eingabemaske sowie im TDBGrid. Daher baue ich einmalig die ganzen möglichen Bitmaps zusammen und halte die in einer Liste. Damit spare ich viel Zeit beim Zeichnen im TDBGrid, da das Bild bereits fertig ist. Das Programm existiert schon lange und heißt EleLa. Nun hat sich ein Linux-User beklagt dass die Rating-Sterne "verschwinden".
Zuletzt geändert von MmVisual am Sa 18. Mai 2013, 20:59, insgesamt 1-mal geändert.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Antworten