Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - Usare il canale trasparenza nei Button
Forum - C# / VB.NET - Usare il canale trasparenza nei Button

Avatar
fosforo (Normal User)
Expert


Messaggi: 391
Iscritto: 06/04/2009

Segnala al moderatore
Postato alle 15:09
Lunedì, 05/10/2020
Ciao

Ho creato un pulsante che chiaramente ha forma regolare.
Vorrei mettere come Background del pulsante una PNG che non ha forma regolare e ha la trasparenza.
Purtroppo dove c'è la trasparenza non vedo la Form ma il colore del pulsante.
Possibile usare la trasparenza della PNG?


Grazie
Fosforo

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1344
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 16:40
Lunedì, 05/10/2020
Si.
Cosa deve trasparire? sul Form c'è un'immagine di sfondo?
Le strade sono due:

1) catturi la parte del form che il button copre in una bitmap in ram, sovrapponi alla bitmap il PNG, poi metti il risultato in Button1.BackgroundImage

2) invece del button metti una picturebox, in PictureBox1.BackgroundImage metti la parte del fom che la pictuerbox copre, in PictureBox1.Image carichi il PNG.

Bisogna solo calcolare un po' di coordinate, scegli il metodo se non riesci ti posto un esempio.

Ultima modifica effettuata da Carlo il 05/10/2020 alle 21:14


in programmazione tutto è permesso
PM Quote
Avatar
fosforo (Normal User)
Expert


Messaggi: 391
Iscritto: 06/04/2009

Segnala al moderatore
Postato alle 8:51
Martedì, 06/10/2020
Grazie Carlo.

Pensavo ci fosse un metodo più professionale.
E' un po micranioso ma con le tue info ci sono riuscito.


Grazie

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1344
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 12:57
Martedì, 06/10/2020
Bravo, per coloro che si imbattono in questo post, posto un esempio per ottenere un bottone o una picturebox che sembra trasparente.
Nel form caricate una immagine di sfondo
Aggiungete una PictureBox1 e un Button1 con Visible=false
nella cartella dell'applicazione mettete un PNG con trasparenza della dimensione che dovrà avere il button o picturebox

Le coordinate che catturano lo schermo potrebbero differire da quelle che ho inserito, esse dipendono dal S.O. e dal tema della finestra, possono essere aggiustate modificando i valori di OffSet

In allegato progetto completo VS, con Click animato su Picturebox, nella cartella Resources immagini di esempio

Codice sorgente - presumibilmente VB.NET

  1. Imports System.IO
  2.  
  3.  
  4. Public Class Form1
  5.     Dim WithEvents Timer1 As System.Windows.Forms.Timer
  6.  
  7.     Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Shown
  8.         Button1.Visible = False ' dobbiamo copiare quello che c'è sotto
  9.         PictureBox1.Visible = False ' dobbiamo copiare quello che c'è sotto
  10.         Timer1.Interval = 300 ' attesa che il form sia completamente visualizzato
  11.         Timer1.Enabled = True
  12.     End Sub
  13.  
  14.     Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
  15.         Timer1.Enabled = False
  16.  
  17.         '************************************************************************************************
  18.         ' bottone trasparente, aggiungi Button1 da progettazione deve vuoi, con Visible = false
  19.         ' La dimesione del PNG determina la dimensione del bottone
  20.         Dim bmpFondo As System.Drawing.Bitmap
  21.         Dim bmpPNG As System.Drawing.Bitmap = Image.FromFile(Path.Combine(Application.StartupPath, "Button.png")) ' metti il nome del tuo png
  22.         bmpFondo = New Bitmap(bmpPNG.Width, bmpPNG.Height) ' stessa dimensione
  23.         Dim Zoom As Integer = 0 ' determina la grandezza dell'immagine png nel bottone
  24.         bmpFondo.SetResolution(bmpPNG.HorizontalResolution + Zoom, bmpPNG.VerticalResolution + Zoom)
  25.         Button1.Size = New Size(bmpPNG.Size) ' stessa dimensione
  26.         Dim gb As Graphics = Graphics.FromImage(bmpFondo) ' layer grafico
  27.         ' copia lo schermo in accordo con le dimensioni di bmpFondo e la posizione di Button1
  28.         Dim OffSetBL As Integer = 8 ' aggiusta la centratura, dipende dallo stile della finestra
  29.         Dim OffSetBT As Integer = 30 ' aggiusta la centratura, dipende dallo stile della finestra
  30.         gb.CopyFromScreen(Me.Left + Button1.Left + OffSetBL, Me.Top + Button1.Top + OffSetBT, 0, 0, bmpFondo.Size, CopyPixelOperation.SourceCopy)
  31.         gb.DrawImage(bmpPNG, Convert.ToInt16(Zoom * -1 / 2), Convert.ToInt16(Zoom * -1 / 2)) ' i calcoli centrano l'immagine
  32.  
  33.         gb.Dispose()
  34.         Button1.BackgroundImage = bmpFondo
  35.         Button1.Visible = True
  36.  
  37.  
  38.         '************************************************************************************************
  39.         ' Picturebox trasparente, aggiungi PictureBox1 da progettazione deve vuoi, con Visible = false
  40.         ' La dimesione del PNG determina la dimensione della Picturebox che simula il bottone
  41.         PictureBox1.Image = Image.FromFile(Path.Combine(Application.StartupPath, "Pickbox.png")) ' metti il nome del tuo png
  42.         PictureBox1.BackgroundImage = New Bitmap(PictureBox1.Image.Width, PictureBox1.Image.Height) ' stessa dimensione ma vuota
  43.         PictureBox1.Size = New Size(PictureBox1.Image.Size) ' stessa dimensione
  44.         PictureBox1.BorderStyle = BorderStyle.FixedSingle ' mette un contorno
  45.         Dim gp As Graphics = Graphics.FromImage(PictureBox1.BackgroundImage) ' layer grafico
  46.         ' copia lo schermo in accordo con le dimensioni della png e la posizione di PictureBox1
  47.         Dim OffSetPL As Integer = 8 ' aggiusta la centratura, dipende dallo stile della finestra
  48.         Dim OffSetPT As Integer = 30 ' aggiusta la centratura, dipende dallo stile della finestra
  49.         gp.CopyFromScreen(Me.Left + PictureBox1.Left + OffSetPL, Me.Top + PictureBox1.Top + OffSetPT, 0, 0, PictureBox1.Size, CopyPixelOperation.SourceCopy)
  50.         gp.Dispose()
  51.         PictureBox1.Visible = True
  52.     End Sub
  53. End Class



Carlo ha allegato un file: PictureBoxLoadFile.zip (559776 bytes)
Clicca qui per scaricare il file

Ultima modifica effettuata da Carlo il 07/10/2020 alle 16:36


in programmazione tutto è permesso
PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2305
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 11:59
Mercoledì, 07/10/2020
C'è un modo molto piu professionale di fare ciò.

Ma bisogna capire esattamente il problema dove sta.

Se imposti la trasparenza "Dal Form" aka Transparency Key
Avrai un buco ovviamente, tranne se in seguito il controllo viene gestito diversamente dal draw.

Testo quotato


Vorrei mettere come Background del pulsante una PNG che non ha forma regolare e ha la trasparenza.
Purtroppo dove c'è la trasparenza non vedo la Form ma il colore del pulsante.
Possibile usare la trasparenza della PNG?




Ci sono due sistemi.
Se il form ha un solo colore come fondo
usa questo

Codice sorgente - presumibilmente C#

  1. public class MioPulsante : Control
  2. {
  3.  
  4.     private Color formcolor;
  5.    public Image ImmaginePulsante  { get; set; }
  6.  
  7.     //Costruttore del controllo
  8.     public MioPulsante()
  9.     {
  10.        SetStyle( ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
  11.  
  12.      
  13.    }
  14.  
  15.     //Alla creazione dell'handle recuperi il color dal form padre
  16.     protected override void OnHandleCreated(EventArgs e)
  17.     {
  18.        formcolor = FindForm().BackColor;
  19.      }
  20.  
  21.     //Al Paint disegni il testo
  22.    protected override void OnPaint(PaintEventArgs e)
  23.         {
  24.              base.OnPaint(e);
  25.  
  26.             Graphics g = e.Graphics;
  27.            g.Clear(formcolor);
  28.             g.SmoothingMode = SmoothingMode.HighQuality;
  29.            g.DrawImage(ImmaginePulsante,e.ClipRectangle);
  30.  
  31.            g.DrawString(Text, Font, new SolidBrush(ForeColor), new PointF(Width/2, 5)); //esempio
  32.          
  33.  
  34. }



Una volta aggiunto il controllo al form, ricorda di impostare il BackColor su Transparent.

L'altra alternativa, al paint, se non ti viene rilevata la trasparenza,

Codice sorgente - presumibilmente C# / VB.NET

  1. Bitmap b = new Bitmap(ImmaginePulsante);
  2. Color c = b.GetPixel(0,0);
  3. b.MakeTransparent(c);
  4.  
  5. g.DrawImage(b);



Credo che cmq il primo esempio dovrebbe andare bene.
PS: Non ho testato il codice ma dovrebbe funzionare.

L'effetto dovrebbe essere tipo come nella mia custom Slider allegata come screen.
A breve caricherò la libreria completa della skin

Quelle frecce laterali sono dei button grafici che al click cambia l'immagine.
come puoi notare sono trasparenti. Non c'è il bordo del controllo.


Thejuster ha allegato un file: Immagine.PNG (180813 bytes)
Clicca qui per guardare l'immagine

Ultima modifica effettuata da Thejuster il 07/10/2020 alle 12:48


https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1344
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 14:29
Mercoledì, 07/10/2020
Testo quotato

Postato originariamente da Thejuster:

C'è un modo molto piu professionale di fare ciò.

Ma bisogna capire esattamente il problema dove sta.

Se imposti la trasparenza "Dal Form" aka Transparency Key
Avrai un buco ovviamente, tranne se in seguito il controllo viene gestito diversamente dal draw.

Testo quotato


Vorrei mettere come Background del pulsante una PNG che non ha forma regolare e ha la trasparenza.
Purtroppo dove c'è la trasparenza non vedo la Form ma il colore del pulsante.
Possibile usare la trasparenza della PNG?





Non avevo interpretato la domanda di fosforo come voler ottenere un bottone con una foma ricavata da un png su uno sfondo uniforme.

Thejuster ha creato un controllo tutto nuovo, bello...;)

Per fare un bottone con un PNG o meglio due PNG, uno cliccato e uno rilasciato userei una picturebox:
Codice sorgente - presumibilmente C++

  1. using System.Windows.Forms;
  2. using System.IO;
  3.  
  4. namespace ButtonPNG
  5. {
  6.     public partial class Form1 : Form
  7.     {
  8.         public Form1()
  9.         {
  10.             InitializeComponent();
  11.             pictureBox1.MouseDown += MouseDown_;
  12.             pictureBox1.MouseUp += MouseUp_;
  13.             pictureBox1.Image = Image.FromFile(Path.Combine(Application.StartupPath, "Rilasciato.png"));
  14.             pictureBox1.Size = pictureBox1.Image.Size;
  15.             pictureBox1.BackColor = this.BackColor;
  16.  
  17.         }
  18.  
  19.         private  void MouseDown_(object sender, EventArgs e)
  20.         {
  21.             pictureBox1.Image = Image.FromFile(Path.Combine(Application.StartupPath, "Cliccato.png"));
  22.         }
  23.  
  24.         private  void MouseUp_(object sender, EventArgs e)
  25.         {
  26.             pictureBox1.Image = Image.FromFile(Path.Combine(Application.StartupPath, "Rilasciato.png"));
  27.         }
  28.     }
  29. }



In allegato progetto, nella cartella debug, due png disegnati al volo.

Comunque da Thejuster c'è sempre da imparare, non conoscevo .MakeTransparent, che è un metodo più "sbrigativo"
Per contorni di bassa qualità o rettangolari, va più che bene, ma con PNG con trasparenze antialiased variegate, rendere solo un colore trasparente ne degrada la qualità in modo inaccettabile. :yup::asd::asd:

Nel mio post precedente ho allegato un progetto: PictureBoxLoadFile.zip, dove si nota la qualità del contorno antialiased


Carlo ha allegato un file: ButtonPNG.zip (389769 bytes)
Clicca qui per scaricare il file

Ultima modifica effettuata da Carlo il 08/10/2020 alle 0:19


in programmazione tutto è permesso
PM Quote