AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

PlgBlt und MaskHandle

Ein Thema von uligerhardt · begonnen am 11. Sep 2017 · letzter Beitrag vom 11. Sep 2017
Antwort Antwort
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#1

PlgBlt und MaskHandle

  Alt 11. Sep 2017, 12:03
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 Mask: HBITMAP da. Wenn ich dem 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:
test1.png

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?
Uli Gerhardt
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#2

AW: PlgBlt und MaskHandle

  Alt 11. Sep 2017, 13:57
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:
test1.png

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

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.
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;
Uli Gerhardt

Geändert von uligerhardt (11. Sep 2017 um 14:41 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: PlgBlt und MaskHandle

  Alt 11. Sep 2017, 14:07
Brauchst du denn PlgBlt zwangsweise? Ginge nicht einfach TransparentBlt und du gibst rot als Transparenz-Farbe an?
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#4

AW: PlgBlt und MaskHandle

  Alt 11. Sep 2017, 14:09
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.

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

Geändert von uligerhardt (11. Sep 2017 um 14:11 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: PlgBlt und MaskHandle

  Alt 11. Sep 2017, 14:13
Edit: Ursprünglich habe ich mit SetWorldTransform rotiert. Das gibt aber seit Kurzem Bluescreens. So wie früher. Unter Windows 95.
Denen komme ich nicht bei, also suche ich nach alternativen Wegen.
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...
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#6

AW: PlgBlt und MaskHandle

  Alt 11. Sep 2017, 14:18
Edit: Ursprünglich habe ich mit SetWorldTransform rotiert. Das gibt aber seit Kurzem Bluescreens. So wie früher. Unter Windows 95.
Denen komme ich nicht bei, also suche ich nach alternativen Wegen.
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.
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.
Uli Gerhardt
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

AW: PlgBlt und MaskHandle

  Alt 11. Sep 2017, 14:29
Hast du vllt vergessen vor SetWorldTransform
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
Ich guck mal ob ich noch was hinkriege.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#8

AW: PlgBlt und MaskHandle

  Alt 11. Sep 2017, 14:45
Hast du vllt vergessen vor SetWorldTransform
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
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.
Uli Gerhardt

Geändert von uligerhardt (11. Sep 2017 um 14:53 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#9

AW: PlgBlt und MaskHandle

  Alt 11. Sep 2017, 14:52
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.
Uli Gerhardt
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:35 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