Oppure

Loading
05/10/20 13:09
fosforo
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
aaa
05/10/20 14:40
Carlo
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 05/10/20 19:14
in programmazione tutto è permesso
06/10/20 6:51
fosforo
Grazie Carlo.

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


Grazie
aaa
06/10/20 10:57
Carlo
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

Imports System.IO


Public Class Form1
    Dim WithEvents Timer1 As System.Windows.Forms.Timer

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Shown
        Button1.Visible = False ' dobbiamo copiare quello che c'è sotto
        PictureBox1.Visible = False ' dobbiamo copiare quello che c'è sotto
        Timer1.Interval = 300 ' attesa che il form sia completamente visualizzato
        Timer1.Enabled = True
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Timer1.Enabled = False

        '************************************************************************************************
        ' bottone trasparente, aggiungi Button1 da progettazione deve vuoi, con Visible = false
        ' La dimesione del PNG determina la dimensione del bottone
        Dim bmpFondo As System.Drawing.Bitmap
        Dim bmpPNG As System.Drawing.Bitmap = Image.FromFile(Path.Combine(Application.StartupPath, "Button.png")) ' metti il nome del tuo png
        bmpFondo = New Bitmap(bmpPNG.Width, bmpPNG.Height) ' stessa dimensione
        Dim Zoom As Integer = 0 ' determina la grandezza dell'immagine png nel bottone
        bmpFondo.SetResolution(bmpPNG.HorizontalResolution + Zoom, bmpPNG.VerticalResolution + Zoom)
        Button1.Size = New Size(bmpPNG.Size) ' stessa dimensione
        Dim gb As Graphics = Graphics.FromImage(bmpFondo) ' layer grafico
        ' copia lo schermo in accordo con le dimensioni di bmpFondo e la posizione di Button1
        Dim OffSetBL As Integer = 8 ' aggiusta la centratura, dipende dallo stile della finestra
        Dim OffSetBT As Integer = 30 ' aggiusta la centratura, dipende dallo stile della finestra
        gb.CopyFromScreen(Me.Left + Button1.Left + OffSetBL, Me.Top + Button1.Top + OffSetBT, 0, 0, bmpFondo.Size, CopyPixelOperation.SourceCopy)
        gb.DrawImage(bmpPNG, Convert.ToInt16(Zoom * -1 / 2), Convert.ToInt16(Zoom * -1 / 2)) ' i calcoli centrano l'immagine

        gb.Dispose()
        Button1.BackgroundImage = bmpFondo
        Button1.Visible = True


        '************************************************************************************************
        ' Picturebox trasparente, aggiungi PictureBox1 da progettazione deve vuoi, con Visible = false
        ' La dimesione del PNG determina la dimensione della Picturebox che simula il bottone
        PictureBox1.Image = Image.FromFile(Path.Combine(Application.StartupPath, "Pickbox.png")) ' metti il nome del tuo png
        PictureBox1.BackgroundImage = New Bitmap(PictureBox1.Image.Width, PictureBox1.Image.Height) ' stessa dimensione ma vuota
        PictureBox1.Size = New Size(PictureBox1.Image.Size) ' stessa dimensione
        PictureBox1.BorderStyle = BorderStyle.FixedSingle ' mette un contorno
        Dim gp As Graphics = Graphics.FromImage(PictureBox1.BackgroundImage) ' layer grafico
        ' copia lo schermo in accordo con le dimensioni della png e la posizione di PictureBox1
        Dim OffSetPL As Integer = 8 ' aggiusta la centratura, dipende dallo stile della finestra
        Dim OffSetPT As Integer = 30 ' aggiusta la centratura, dipende dallo stile della finestra
        gp.CopyFromScreen(Me.Left + PictureBox1.Left + OffSetPL, Me.Top + PictureBox1.Top + OffSetPT, 0, 0, PictureBox1.Size, CopyPixelOperation.SourceCopy)
        gp.Dispose()
        PictureBox1.Visible = True
    End Sub
End Class
Ultima modifica effettuata da Carlo 07/10/20 14:36
in programmazione tutto è permesso
07/10/20 9:59
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.

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


public class MioPulsante : Control
{

    private Color formcolor;
   public Image ImmaginePulsante  { get; set; }

    //Costruttore del controllo
    public MioPulsante()
    {
       SetStyle( ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);

      
   }

    //Alla creazione dell'handle recuperi il color dal form padre
    protected override void OnHandleCreated(EventArgs e)
    {
       formcolor = FindForm().BackColor;
     }

    //Al Paint disegni il testo
   protected override void OnPaint(PaintEventArgs e)
        {
             base.OnPaint(e);

            Graphics g = e.Graphics;
           g.Clear(formcolor);
            g.SmoothingMode = SmoothingMode.HighQuality;
           g.DrawImage(ImmaginePulsante,e.ClipRectangle);

           g.DrawString(Text, Font, new SolidBrush(ForeColor), new PointF(Width/2, 5)); //esempio
         

}



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,


Bitmap b = new Bitmap(ImmaginePulsante);
Color c = b.GetPixel(0,0);
b.MakeTransparent(c);

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.
Ultima modifica effettuata da Thejuster 07/10/20 10:48
mire.forumfree.it/ - Mire Engine
C# UI Designer
07/10/20 12:29
Carlo
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.

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:
using System.Windows.Forms;
using System.IO;

namespace ButtonPNG
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            pictureBox1.MouseDown += MouseDown_;
            pictureBox1.MouseUp += MouseUp_;
            pictureBox1.Image = Image.FromFile(Path.Combine(Application.StartupPath, "Rilasciato.png"));
            pictureBox1.Size = pictureBox1.Image.Size;
            pictureBox1.BackColor = this.BackColor;

        }

        private  void MouseDown_(object sender, EventArgs e)
        {
            pictureBox1.Image = Image.FromFile(Path.Combine(Application.StartupPath, "Cliccato.png"));
        }

        private  void MouseUp_(object sender, EventArgs e)
        {
            pictureBox1.Image = Image.FromFile(Path.Combine(Application.StartupPath, "Rilasciato.png"));
        }
    }
}


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
Ultima modifica effettuata da Carlo 07/10/20 22:19
in programmazione tutto è permesso