Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   PlgBlt und MaskHandle (https://www.delphipraxis.net/193800-plgblt-und-maskhandle.html)

uligerhardt 11. Sep 2017 11:03

PlgBlt und MaskHandle
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen!

Ich möchte ein TBitmap "bmp" rotiert zeichnen. Dazu verwende ich PlgBlt. Leider wird dabei erstmal die Transparenz nicht berücksichtigt. Dafür ist wohl der Parameter
Delphi-Quellcode:
Mask: HBITMAP
da. Wenn ich dem
Delphi-Quellcode:
bmp.MaskHandle
übergebe, wird allerdings mein Bitmap wegmaskiert, nicht die transparenten Teile.

Hier mal Testcode:
Delphi-Quellcode:
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  bmp: TBitmap;
  r: TRect;
  Points: array[0..2] of TPoint;
begin
  bmp := TBitmap.Create;
  try
    bmp.LoadFromFile('test.bmp');
    bmp.Transparent := True;

    SetRect(r, 0, 0, bmp.Width, bmp.Height);
    PaintBox1.Canvas.StretchDraw(r, bmp);

    OffsetRect(r, bmp.Width + 2, 0);
    Points[0] := Point(r.Left, r.Top);
    Points[1] := Point(r.Right, r.Top);
    Points[2] := Point(r.Left, r.Bottom);
    PlgBlt(PaintBox1.Canvas.Handle, Points, bmp.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, 0, 0, 0);

    OffsetRect(r, bmp.Width + 2, 0);
    Points[0] := Point(r.Left, r.Top);
    Points[1] := Point(r.Right, r.Top);
    Points[2] := Point(r.Left, r.Bottom);
    PlgBlt(PaintBox1.Canvas.Handle, Points, bmp.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, bmp.MaskHandle, 0, 0);
  finally
    bmp.Free;
  end;
end;
Der liefert das:
Anhang 47863

Das Originalbitmap schaut wie in der Mitte aus. Ich möchte den "Look" links, kriege aber mit PlgBlt das Ergebnis rechts.

Ich könnte mir selbst ein Maskenbitmap zusammenbasteln, aber TBitmap.MaskHandle ist doch genau dafür da:
Zitat:

Use MaskHandle to call a Windows API function that requires the handle of a bitmap object. Pass MaskHandle as the bitmap handle parameter to these functions.
Hab ich da was übersehen?

uligerhardt 11. Sep 2017 12:57

AW: PlgBlt und MaskHandle
 
Liste der Anhänge anzeigen (Anzahl: 1)
So, ich hab mal eine Lösung, wenn auch eher unelegant:
Delphi-Quellcode:
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  bmp, mask, mask2: TBitmap;
  r: TRect;
  Points: array[0..2] of TPoint;
begin
  bmp := TBitmap.Create;
  try
    bmp.LoadFromFile('test.bmp');
    bmp.Transparent := True;

    SetRect(r, 0, 0, bmp.Width, bmp.Height);
    PaintBox1.Canvas.Draw(r.Left, r.Top, bmp);

    OffsetRect(r, bmp.Width + 2, 0);
    Points[0] := Point(r.Left, r.Top);
    Points[1] := Point(r.Right, r.Top);
    Points[2] := Point(r.Left, r.Bottom);
    PlgBlt(PaintBox1.Canvas.Handle, Points, bmp.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, 0, 0, 0);

    OffsetRect(r, bmp.Width + 2, 0);
    Points[0] := Point(r.Left, r.Top);
    Points[1] := Point(r.Right, r.Top);
    Points[2] := Point(r.Left, r.Bottom);
    mask := TBitmap.Create;
    try
      mask.SetSize(bmp.Width, bmp.Height);
      mask.Monochrome := True;
      mask.PixelFormat := pfDevice;

      mask2 := TBitmap.Create;
      try
        mask2.Handle := bmp.MaskHandle;
        BitBlt(mask.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, mask2.Canvas.Handle, 0, 0, NOTSRCCOPY);
      finally
        mask2.Free;
      end;

      PlgBlt(PaintBox1.Canvas.Handle, Points, bmp.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, mask.Handle, 0, 0);
    finally
      mask.Free;
    end;
  finally
    bmp.Free;
  end;
end;
Ergebnis:
Anhang 47865

Wenn jemand eine Idee hat, wie ich das ohne die zwei Zwischenbitmaps Mask/mask2 hinkriege, immer her damit! :mrgreen:

Update: MaskHandle geht anscheinend bei erstmaliger Verwendung kaputt, also besser so:
Delphi-Quellcode:
      mask2 := TBitmap.Create;
      try
        //mask2.Handle := bmp.MaskHandle; Funktioniert nur einmalig - ist danach kaputt???
        mask2.Assign(bmp);
        mask2.Mask(bmp.Canvas.Pixels[0, bmp.Height - 1]);
        BitBlt(mask.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, mask2.Canvas.Handle, 0, 0, NOTSRCCOPY);
      finally
        mask2.Free;
      end;
Update2: Klar geht's kaputt, wenn man's an mask2 dranhängt und dann mask2.Free aufruft. :oops::wall:
Also so:
Delphi-Quellcode:
      mask2 := TBitmap.Create;
      try
        mask2.Handle := bmp.MaskHandle;
        BitBlt(mask.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, mask2.Canvas.Handle, 0, 0, NOTSRCCOPY);
        mask2.ReleaseHandle;
      finally
        mask2.Free;
      end;

Neutral General 11. Sep 2017 13:07

AW: PlgBlt und MaskHandle
 
Brauchst du denn PlgBlt zwangsweise? Ginge nicht einfach TransparentBlt und du gibst rot als Transparenz-Farbe an?

uligerhardt 11. Sep 2017 13:09

AW: PlgBlt und MaskHandle
 
Zitat:

Zitat von Neutral General (Beitrag 1380772)
Brauchst du denn PlgBlt zwangsweise? Ginge nicht einfach TransparentBlt und du gibst rot als Transparenz-Farbe an?

Ja, ich will ja rotieren. Mein Testcode gibt das zugegebenermaßen nicht wieder. :mrgreen:

Edit: Ursprünglich habe ich mit SetWorldTransform rotiert. Das gibt aber seit Kurzem Bluescreens. So wie früher. Unter Windows 95. :shock::pale:
Denen komme ich nicht bei, also suche ich nach alternativen Wegen.

Neutral General 11. Sep 2017 13:13

AW: PlgBlt und MaskHandle
 
Zitat:

Zitat von uligerhardt (Beitrag 1380773)
Edit: Ursprünglich habe ich mit SetWorldTransform rotiert. Das gibt aber seit Kurzem Bluescreens. So wie früher. Unter Windows 95. :shock::pale:
Denen komme ich nicht bei, also suche ich nach alternativen Wegen.

:shock: Sicher dass du da nicht irgendwas böse falsch gemacht hast oder dass da an deinem Windows nicht irgendwas kaputt ist?
Ich probier mal grad was...

uligerhardt 11. Sep 2017 13:18

AW: PlgBlt und MaskHandle
 
Zitat:

Zitat von Neutral General (Beitrag 1380775)
Zitat:

Zitat von uligerhardt (Beitrag 1380773)
Edit: Ursprünglich habe ich mit SetWorldTransform rotiert. Das gibt aber seit Kurzem Bluescreens. So wie früher. Unter Windows 95. :shock::pale:
Denen komme ich nicht bei, also suche ich nach alternativen Wegen.

:shock: Sicher dass du da nicht irgendwas böse falsch gemacht hast oder dass da an deinem Windows nicht irgendwas kaputt ist?
Ich probier mal grad was...

Nö, nicht sicher. :oops:
Ist bloß etwas diffizil zu debuggen, wenn dauernd der Rechner neu bootet. Und es tritt scheinbar auch erst seit Neuerem auf, unter Windows 7 und 10. Drum vermute ich, dass irgendwelche Updates an Graphiksubsystem oder -kartentreibern mit reinspielen.

Neutral General 11. Sep 2017 13:29

AW: PlgBlt und MaskHandle
 
Hast du vllt vergessen vor SetWorldTransform
Delphi-Quellcode:
SetGraphicsMode(Canvas.Handle, GM_ADVANCED)

aufzurufen?

Bei mir stürzt es nicht ab aber es tut auch nichts. wahrscheinlich weil ich zu blöd für Matrizen bin :oops:
Ich guck mal ob ich noch was hinkriege.

uligerhardt 11. Sep 2017 13:45

AW: PlgBlt und MaskHandle
 
Zitat:

Zitat von Neutral General (Beitrag 1380781)
Hast du vllt vergessen vor SetWorldTransform
Delphi-Quellcode:
SetGraphicsMode(Canvas.Handle, GM_ADVANCED)

aufzurufen?

Bei mir stürzt es nicht ab aber es tut auch nichts. wahrscheinlich weil ich zu blöd für Matrizen bin :oops:
Ich guck mal ob ich noch was hinkriege.

SetGraphicsMode hab ich schon - im Normalfall geht's ja auch. Bis ich den Bluescreen bei mir nachvollziehen konnte, musste ich ewig probieren. Scheinbar kommt es drauf an, wo genau auf dem Bildschirm das Bitmap landet.

uligerhardt 11. Sep 2017 13:52

AW: PlgBlt und MaskHandle
 
Zitat:

Zitat von Neutral General (Beitrag 1380775)
:shock: Sicher dass du da nicht irgendwas böse falsch gemacht hast oder dass da an deinem Windows nicht irgendwas kaputt ist?
Ich probier mal grad was...

Ist leider nicht nur mein Windows. Zuerst ist das Problem nach und nach bei Kunden mit Windows 10 aufgetaucht. Mittlerweile kann ich es auf meiner Windows7-Testkiste nachvollziehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:28 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz