AGB  ·  Datenschutz  ·  Impressum  







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

Region vom Bitmap erstellen...

Ein Thema von turboPASCAL · begonnen am 5. Sep 2009 · letzter Beitrag vom 3. Aug 2011
Antwort Antwort
Seite 1 von 2  1 2      
Progman

Registriert seit: 31. Aug 2007
Ort: 99974 MHL
695 Beiträge
 
Delphi 10.1 Berlin Starter
 
#1

Re: Region vom Bitmap erstellen...

  Alt 6. Sep 2009, 09:51
Meinst du sowas?
Delphi-Quellcode:
type
  TRGBArray = array[0..32767] of TRGBTriple;
  PRGBArray = ^TRGBArray;

type
  TfrmMain = class(TForm)
    ...
  private
    { Private-Deklarationen }
    HG: TBitmap;
    FRegion: THandle;
    function CreateRegion(Bmp: TBitmap): THandle;
  public
    ...
  end;

implementation

function TfrmMain.CreateRegion(Bmp: TBitmap): THandle;
var
  X, Y, StartX: Integer;
  Excl: THandle;
  Row: PRGBArray;
  TransparentColor: TRGBTriple;
begin
  Bmp.PixelFormat := pf24Bit;
  Result := CreateRectRGN(0, 0, Bmp.Width, Bmp.Height);
  for Y := 0 to Bmp.Height - 1 do
  begin
    Row := Bmp.Scanline[Y];
    StartX := -1;
    if Y = 0 then
      TransparentColor := Row[0];
    for X := 0 to Bmp.Width - 1 do
    begin
      if (Row[X].rgbtRed = TransparentColor.rgbtRed) and
        (Row[X].rgbtGreen = TransparentColor.rgbtGreen) and
        (Row[X].rgbtBlue = TransparentColor.rgbtBlue) then
      begin
        if StartX = -1 then StartX := X;
      end
      else
      begin
        if StartX > -1 then
        begin
          Excl := CreateRectRGN(StartX, Y, X + 1, Y + 1);
          try
            CombineRGN(Result, Result, Excl, RGN_DIFF);
            StartX := -1;
          finally
            DeleteObject(Excl);
          end;
        end;
      end;
    end;
    if StartX > -1 then
    begin
      Excl := CreateRectRGN(StartX, Y, Bmp.Width, Y + 1);
      try
        CombineRGN(Result, Result, Excl, RGN_DIFF);
      finally
        DeleteObject(Excl);
      end;
    end;
  end;
end;


//Borderstyle muss bsNone sein
procedure TfrmMain.FormCreate(Sender: TObject);
var Bmp: TBitmap;
begin
  HG:=TBitmap.Create;
  HG.LoadFromFile(ResPath+'Monitor.bmp');
  Bmp := TBitmap.Create;
  try
    bmp.Assign(HG);
    Width:=HG.Width;
    ClientHeight:=HG.Height;
    FRegion := CreateRegion(Bmp);
    SetWindowRGN(Handle, FRegion, True);
  finally
    Bmp.Free;
  end;
  ...
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
  DeleteObject(FRegion);
  HG.Free;
end;

procedure TfrmMain.FormPaint(Sender: TObject);
begin
  BitBlt(canvas.handle, 0, 0, Clientwidth, Clientheight,HG.Canvas.handle, 0, 0, SRCCOPY);
end;
Das erzeugt einer Region anhand eines Bitmaps. Das Fenster hat dann die Form des Bitmaps. Als transparent wird die Farbe der Pixels 0,0 festgelegt (glaub ich)
Karl-Heinz
Populanten von Domizilen mit fragiler, transparenter Aussenstruktur sollten sich von der Translation von gegen Deformierung resistenter Materie distanzieren!
(Wer im Glashaus sitzt sollte nicht mit Steinen werfen)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#2

AW: Region vom Bitmap erstellen...

  Alt 28. Jul 2011, 04:43
Ich möchte meinen Button eine region verpassen
Mit Standard Button (TButton) funktioniert das aber leider nicht mit nonvcl Button.

Habe es mal mit beiden Functionen versucht.
Diese hier..
http://www.delphipraxis.net/948896-post5.html

und

auf dieser Seite.
http://www.delphipraxis.net/404171-post7.html


beides will nicht funktionieren.
Warum ist mir schleierhaft.

jemand eine Idee?


Delphi-Quellcode:
      if Region > 0 then
      begin
        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 := BitmapToRegion(ABitmap.Handle, imgw, imgh, RGB(255,0,255), 0);
            SetWindowRgn(FHImageButton, ARgn, True);
            ABitmap.Free;
          end else
          begin
            // Lösche das Image
            SkinEngine.DeleteResource(hOwner, Img);
          end;
        end;

gruss

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

n/a Beiträge
 
#3

AW: Region vom Bitmap erstellen...

  Alt 28. Jul 2011, 06:32
Push ..

Hab mal ein Button Beispiel von Luckie umgestrickt. (nonvcl)
Also der Rosa bereich des Button soll abgeschnitten werden.

Vielleicht schaut ja mal jemand in den Sample rein.

gruss

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

n/a Beiträge
 
#4

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
44.340 Beiträge
 
Delphi 12 Athens
 
#5

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.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

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
44.340 Beiträge
 
Delphi 12 Athens
 
#7

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.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

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

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.
Angehängte Grafiken
Dateityp: jpg Image1.jpg (47,2 KB, 29x aufgerufen)
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
 
#9

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
 
#10

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
Antwort Antwort
Seite 1 von 2  1 2      


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 14:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz