AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Region vom Bitmap erstellen...

Ein Thema von turboPASCAL · begonnen am 5. Sep 2009 · letzter Beitrag vom 3. Aug 2011
Antwort Antwort
Seite 2 von 3     12 3   
EWeiss
(Gast)

n/a Beiträge
 
#11

AW: Region vom Bitmap erstellen...

  Alt 29. Jul 2011, 00:59
Niemand eine Idee?

gruss
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.097 Beiträge
 
Delphi 12 Athens
 
#12

AW: Region vom Bitmap erstellen...

  Alt 29. Jul 2011, 06:08
Ich dachte mal, daß ich da auch irgendwann einmal sowas gesehn hatte,
abr als ich letztens danach suchte, fand ich nur eine (etwas langsame) Funktion, welche das Bild Pixelweise auslas und dieses in eine Region eintrug.

Wäre och gespannt, ob es dennoch was Besseres gibt.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#13

AW: Region vom Bitmap erstellen...

  Alt 29. Jul 2011, 07:21
Wenn du mein projekt im vorherigen Thread mal laden würdest
Button.rar.

Grundsätzlich funktioniert das ja aber nur in der VCL mit einem TButton nicht in nonvcl.
Das ist was mich stutzig macht.

gruss
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.097 Beiträge
 
Delphi 12 Athens
 
#14

AW: Region vom Bitmap erstellen...

  Alt 29. Jul 2011, 08:24
Oh komma, hier gibt es ja nocheine Seite.


Na mal sehn ... vielleicht schau ich am WE nochmal rein.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#15

AW: Region vom Bitmap erstellen...

  Alt 31. Jul 2011, 13:37
Ich möchte meinen Button eine region verpassen
Mit Standard Button (TButton) funktioniert das aber leider nicht mit nonvcl Button.
Doch, das tut es.


beides will nicht funktionieren.
Warum ist mir schleierhaft.

jemand eine Idee?
Ja.

Man muss die richtigen Window-Attribute setzen.
Miniaturansicht angehängter Grafiken
image1.jpg  
Angehängte Dateien
Dateityp: zip RGNButtonTest.zip (128,5 KB, 14x aufgerufen)
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#16

AW: Region vom Bitmap erstellen...

  Alt 31. Jul 2011, 15:15
Zitat:
Man muss die richtigen Window-Attribute setzen.
oops .. werd es mir direkt anschauen was ich da wieder verzapft habe das es nicht ging.

EDIT:
Nur WS_CLIPSIBLINGS vergessen?

EDIT2:
Doch nicht so einfach.. hmmm
Warum wird der Button trotzdem gedrückt obwohl ich im leeren bereich klicke?

Es sieht also so aus das ich das Bitmap selbst auch noch ausschneiden muss.
Was aber eigentlich wenn der bereich Transparent ist nicht nötig sein sollte.

gruss Emil

Geändert von EWeiss (31. Jul 2011 um 16:23 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#17

AW: Region vom Bitmap erstellen...

  Alt 1. Aug 2011, 01:31
Will immer noch nicht so wie ich es will

Siehe Bild!

Delphi-Quellcode:
      if Region > 0 then
      begin
      Style := WS_CHILD or WS_VISIBLE or WS_CLIPSIBLINGS or BS_PUSHBUTTON;
      if ButID = ID_LED then
          Style := Style or WS_DISABLED;

        GdipLoadImageFromFile(PWideChar(FullPathImageName), img);
        GdipCreateHBITMAPFromBitmap(pointer(img), hbmReturn, $000000);
        if hbmReturn <> 0 then
        begin
          ABitmap := TBitmap.Create;
          ABitmap.Handle := hbmReturn;
          ABitmap.Width := btW;
          ABitmap.Height:= btH;

          FHImageButton := CreateWindowEx(WS_EX_TRANSPARENT, SKIMAGEBUTTON,
            '', Style, x, y, btW, btH, hOwner, ButID, SkinEngine.skInstance, nil);
          if FHImageButton <> 0 then
          begin
            SkinEngine.SetImageProperty(FHImageButton, PROP_IMAGE_BACK, Img);
            SkinEngine.SetImageProperty(FHImageButton, PROP_STYLE, BS_BITMAP);
            SkinEngine.SetImageProperty(FHImageButton, PROP_STATEMAX, StateMax);

            ARgn := RegionFromBitmap(ABitmap.Handle, $FF00FF);
            SetWindowRgn(FHImageButton, ARgn, true);

            ABitmap2 := TBitmap.Create;
            ABitmap2.Width := ImgW;
            ABitmap2.Height:= ImgH;

            ARgn2 := RegionFromBitmap(hbmReturn, $FF00FF);
            SetWindowRgn(ABitmap2.Handle, ARgn2, true);

            ABitmap2.Free;
            ABitmap.Free;
          end else
          begin
            // Lösche das Image
            SkinEngine.DeleteResource(hOwner, Img);
          end;
        end;
      end
Ich erstelle ein HBitmap vom Bitmap
Danach jage ich ABitmap durch die Function RegionFromBitmap
Der Button wird dann Ordnungsgemäß ausgeschnitten.

Aber wie man sieht kann man immer noch den Bereich Magenta des Images sehen.
Ich dachte eigentlich das der ausgeschnittene Bereich des Button wenn ein Image überlagert wird nicht mehr sichtbar sein sollte.
Ist er aber...

Nun gehe ich hin und erstelle eine zusätzliche Maske vom Image selbst das als Strip abgelegt ist
und 2 Bilder in einem enthält. Down/Up Status.

Delphi-Quellcode:
function TSkinImageButton.RegionFromBitmap(hbmp: HBitmap;
  TransColor: ColorRef): HRGN;

type
  TRectArray = array[0..0] of TRect;
var
  bm: Bitmap;
  pData: PRgnData;
  lpRect: PRect;
  hRgn2: HRGN;
  hRgn1: HRGN;
  sRegionData: THandle;
  MaxRegions: integer;
  I, J, K, M: integer;
  pr: ^TRectArray;
  p32: PByte;
  lPixel: PRGBQuad;

begin

  hRgn1 := 0;
  lPixel := nil;

  GetObject(hbmp, SIZEOF(bm), @bm);

  if TransColor = 0 then
    TransColor := cardinal(lPixel) and $FFFFFF;

  MaxRegions := 4000;

  sRegionData := GlobalAlloc(GMEM_MOVEABLE, SizeOf(RGNDATAHEADER) +
    SizeOf(TRECT) * MaxRegions);
  pData := GlobalLock(sRegionData);
  pData^.rdh.nCount := 0;
  pData^.rdh.dwSize := sizeof(RGNDATAHEADER);
  pData^.rdh.iType := RDH_RECTANGLES;
  pData^.rdh.nRgnSize := 0;
  pData^.rdh.rcBound.Left := 0;
  pData^.rdh.rcBound.Top := 0;
  pData^.rdh.rcBound.Right := bm.bmWidth;
  pData^.rdh.rcBound.Bottom := bm.bmHeight;

  lpRect := PRECT(@pData^.Buffer);

  p32 := PByte(integer(bm.bmBits) + (bm.bmHeight - 1) * bm.bmWidthBytes);
  for J := 0 to bm.bmHeight - 1 do
  begin
    I := 0;
    while I < bm.bmWidth do
    begin
      M := I;

      lPixel := Pointer(integer(p32) + I * SizeOf(cardinal));
      while I < bm.bmWidth do
      begin
        K := MakeColor(0, lPixel^.rgbRed, lPixel^.rgbGreen, lPixel^.rgbBlue) and
          $FFFFFF;

        if K <> integer(TransColor) then
        begin
          Inc(I);
          Inc(lPixel);
        end
        else
          Break;
      end;

      if I > M then
      begin
        if integer(pData^.rdh.nCount) >= MaxRegions then
        begin
          hRgn2 := ExtCreateRegion(nil, sizeof(RGNDATAHEADER) +
            (sizeof(TRECT) * pData^.rdh.nCount), PRGNDATA(pData)^);
          if hRgn1 = 0 then
          begin
            hRgn1 := hRgn2;
          end
          else
          begin
            CombineRgn(hRgn1, hRgn1, hRgn2, RGN_OR);
            SkinEngine.skDeleteObject(hRgn2);
          end;
          pData^.rdh.nCount := 0;
        end;

        pr := @pData^.Buffer;
        SetRect(pr^[pData^.rdh.nCount], M, J, I, J + 1);
        if M < lpRect.Left then
          lpRect.Left := M;
        if I > lpRect.Right then
          lpRect.Right := I;
        if J < lpRect.Top then
          lpRect.Top := J;
        if J > lpRect.Bottom then
          lpRect.Bottom := J + 1;
        Inc(pData^.rdh.nCount);
        Inc(lpRect);
      end;

      Inc(I);
    end;
    Dec(p32, bm.bmWidthBytes);
  end;

  hRgn2 := ExtCreateRegion(nil, sizeof(RGNDATAHEADER) +
    (sizeof(TRECT) * pData^.rdh.nCount), pData^);

  if hRgn1 = 0 then
  begin
    hRgn1 := hRgn2;
  end
  else
  begin
    CombineRgn(hRgn1, hRgn1, hRgn2, RGN_OR);
    DeleteObject(hRgn2);
  end;

  GlobalFree(sRegionData);
  DeleteObject(hbmp);

  Result := hRgn1;

end;
Jetzt jage ich ABitmap2 ebenfalls durch diese Function.
Aber der Magenta bereich wird nicht ausgeschnitten bzw. das Bitmap nicht aktualisiert.

Delphi-Quellcode:
ARgn2 := RegionFromBitmap(hbmReturn, $FF00FF);
SetWindowRgn(ABitmap2.Handle, ARgn2, true);
Ist das Handle vom ABitmap2 nicht gültig ?
Oder woran hapert es denn jetzt schon wieder.

Kann zwar den Magenta Bereich mit den Halbton Button überlagern dann tritt aber das problem hier auf.

Klicke ich die C Taste geht alles wunderbar wenn ich aber nach dem loslassen dann C# klicke und in dem Magentabereich der C Taste komme
dann werden zwei Töne gleichzeitig gespielt. C+C#

Puhh hoffe dass das noch jemand ließt.

PS:
Das Image transparent im bereich Magenta zu machen (müßte dann ein zusätzliches MaskImg anlegen um den Button auszuschneiden) bringt auch nichts.
Auch hier werden 2 Tasten betätigt wenn ich auf den Transparenten bereich klicke (Das ist der aktuelle status was weg soll).

gruss

Geändert von EWeiss (11. Jul 2019 um 15:40 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#18

AW: Region vom Bitmap erstellen...

  Alt 3. Aug 2011, 17:32
Es will einfach nicht.
Ich ersetze jetzt die Farbe mit

Delphi-Quellcode:
            if SkinEngine.GetProperty(Winhandle, PROP_REGION) = 1 then
            begin
              if GdipCreateImageAttributes(ImgAtt) = 0 then
              begin
                TransColor := SkinEngine.ColorARGB(255, RGB(255, 0, 255));
                if GdipSetImageAttributesColorKeys(ImgAtt, ColorAdjustTypeDefault, True, 0, TransColor) = 0 then
                begin
                  GdipDrawImageRectRectI(Graphics, Img,
                    x, y, ImgW, ImgH,
                    ImgW * cardinal(UseState) - ImgW, 0, ImgW, ImgH, 2,
                    ImgAtt, False, nil)
                end;
              end;
            end else
            GdipDrawImageRectRectI(Graphics, Img,
              x, y, ImgW, ImgH,
              ImgW * cardinal(UseState) - ImgW, 0, ImgW, ImgH, 2,
              nil, False, nil);
aber das Resultat ist das gleiche als wenn ich den bereich direkt Transparent mache im Bitmap selbst.
Warum läßt sich das Bitmap nicht ausschneiden?
geht doch beim Button auch.. hmmm

Oder ist es möglich das nach dem down status des Button die Region von diesen wieder auf default gesetzt wird?
Sehen kann ich das nicht.
Seltsamerweise Wenn ich noch keinen Button geklickt habe lassen sich keine zwei Button gleichzeitig drücken.

gruss

Geändert von EWeiss ( 3. Aug 2011 um 17:40 Uhr)
  Mit Zitat antworten Zitat
Tryer

Registriert seit: 16. Aug 2003
200 Beiträge
 
#19

AW: Region vom Bitmap erstellen...

  Alt 3. Aug 2011, 18:34
Warum heißt SetWindowRgn wohl SetWindowRgn?

Richtig, weil es für Fenster, sprich TWinControls funktioniert.
Ein TBitmap.Handle hat nichts damit zu tun, ist nur "leider" zuweisungskompatibel da es halt auch eine einfache "Hausnummer" ist(LongWord).

Nimm ein TWinControl (z.B. TPanel), packt das Image drauf und wende SetWindowRgn auf Panel.Handle an.

Grüsse, Dirk
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#20

AW: Region vom Bitmap erstellen...

  Alt 3. Aug 2011, 19:16
Warum heißt SetWindowRgn wohl SetWindowRgn?

Richtig, weil es für Fenster, sprich TWinControls funktioniert.
Ein TBitmap.Handle hat nichts damit zu tun, ist nur "leider" zuweisungskompatibel da es halt auch eine einfache "Hausnummer" ist(LongWord).

Nimm ein TWinControl (z.B. TPanel), packt das Image drauf und wende SetWindowRgn auf Panel.Handle an.

Grüsse, Dirk
Vergess es! (Auch wenn du recht hast mit dem SetWindowRgn)
Zeig mal wie du in einer Nonvcl Anwendung ein TPanel oder was auch immer deiner meinung nach dafür passt einbinden willst.

Mein Problem mit dem Bitmap hab ich schon gelößt wie im vorherigen Beitrag mitgeteilt.
GdipSetImageAttributesColorKeys

Zitat:
Ich denke das mein Problem daran liegt das nach dem Down status des button der alte(original) zustand wieder hergestellt wird.
Der Button scheint dann nicht mehr ausgeschnitten zu sein.
Die frage wäre dann wie kann ich die einmal erstellte region erhalten auch nach dem klick auf den Button.
bzw.. dem Up Status zuweisen.

Der ja von WinControls abgeleitet ist
Seltsamer weise funktioniert das ja beim Beispiel von turboPASCAL
Quatsch liegt immer noch am Bitmap.
Auch wenn es jetzt wieder transparent ist wird ein Klickevent auf dem Transparenten bereich ausgeführt.
Hat mit dem Ausgeschnittenen Button nix zu tun das funktioniert nach nochmaligen testen.


PS:
Ach so das Panel auf einen Button knallen würde ja auch nicht gehn.
So einfach ist es also nicht.

gruss

Geändert von EWeiss ( 3. Aug 2011 um 19:46 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 12:54 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