web-dev-qa-db-fra.com

Images transparentes avec C # WinForms

Je travaille sur une application Windows Forms dans VS 2008 et je souhaite afficher une image par-dessus une autre, l’image supérieure étant un gif ou un élément comportant des parties transparentes.

En gros, j'ai une grande image et je veux mettre une petite image dessus pour qu'elle apparaisse un peu comme une image pour l'utilisateur.

J'ai essayé d'utiliser une boîte à images, mais cela ne semble pas avoir fonctionné, des suggestions?

22
Fiona

J'étais dans une situation similaire il y a quelques jours. Vous pouvez créer un contrôle transparent pour héberger votre image.

using System;
using System.Windows.Forms;
using System.Drawing;

public class TransparentControl : Control
{
    private readonly Timer refresher;
    private Image _image;

    public TransparentControl()
    {
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        BackColor = Color.Transparent;
        refresher = new Timer();
        refresher.Tick += TimerOnTick;
        refresher.Interval = 50;
        refresher.Enabled = true;
        refresher.Start();
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x20;
            return cp;
        }
    }

    protected override void OnMove(EventArgs e)
    {
        RecreateHandle();
    }


    protected override void OnPaint(PaintEventArgs e)
    {
        if (_image != null)
        {
            e.Graphics.DrawImage(_image, (Width / 2) - (_image.Width / 2), (Height / 2) - (_image.Height / 2));
        }
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
       //Do not Paint background
    }

    //Hack
    public void Redraw()
    {
        RecreateHandle();
    }

    private void TimerOnTick(object source, EventArgs e)
    {
        RecreateHandle();
        refresher.Stop();
    }

    public Image Image
    {
        get
        {
            return _image;
        }
        set
        {
            _image = value;
            RecreateHandle();
        }
    }
}
25
Leon Tayson

PictureBox comporte 2 couches d'images: BackgroundImage et Image, que vous pouvez utiliser indépendamment l'une de l'autre, y compris le dessin et la suppression.

6
Nav

Placez l'image grand/en bas sur une PictureBox, puis ajoutez un gestionnaire à l'événement OnPaint et utilisez l'une des surcharges e.Graphics.DrawImage(). Vous pouvez charger l'image à l'aide de Image.FromFile().

La petite/image supérieure devra avoir un canal alpha et être transparente en arrière-plan pour que la superposition fonctionne. Vous devriez pouvoir vous en assurer assez facilement dans Photoshop ou quelque chose de similaire. Veillez à enregistrer dans un format prenant en charge le canal alpha, tel que PNG.

4
Jon Grant

Le code vb.net (tous les crédits à Leon Tayson):

Imports System
Imports System.Windows.Forms
Imports System.Drawing

Public Class TransparentControl
    Inherits Control

    Private ReadOnly Local_Timer As Timer
    Private Local_Image As Image

    Public Sub New()
        SetStyle(ControlStyles.SupportsTransparentBackColor, True)
        BackColor = Color.Transparent
        Local_Timer = New Timer
        With Local_Timer
            .Interval = 50
            .Enabled = True
            .Start()
        End With

        AddHandler Local_Timer.Tick, AddressOf TimerOnClick

    End Sub

    Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
        Get
            Dim cp As CreateParams
            cp = MyBase.CreateParams
            cp.ExStyle = &H20
            Return cp
        End Get
    End Property

    Protected Overrides Sub OnMove(ByVal e As System.EventArgs)
        MyBase.OnMove(e)
        RecreateHandle()
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)

        If Local_Image IsNot Nothing Then _
            e.Graphics.DrawImage(Local_Image, New Rectangle(0, 0, (Width / 2) - (Local_Image.Width / 2), (Height / 2) - (Local_Image.Height / 2)))

    End Sub

    Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs)
        ' DO NOT Paint BACKGROUND
    End Sub

    ''' <summary>
    ''' Hack
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub ReDraw()
        RecreateHandle()
    End Sub

    Private Sub TimerOnClick(ByVal sender As Object, ByVal e As System.EventArgs)
        RecreateHandle()
        Local_Timer.Stop()

    End Sub

    Public Property Image As Image
        Get
            Return Local_Image
        End Get
        Set(ByVal value As Image)
            Local_Image = value
            RecreateHandle()
        End Set
    End Property
End Class
3
MiBol

Une liste de messages similaires est référencée au bas de cette réponse.

Cette réponse adresse pictureBoxes et Winforms (dans les autres articles ci-dessous, plusieurs personnes répètent que WPF résout déjà ce problème)

  1. Créer Winform
  2. Créer x2 PictureBoxes
    • foreground_pictureBox // bloc d'image 'devant' de 'arrière-plan'
    • background_pictureBox // boîte à images 'derrière' le 'premier plan'
  3. Ajoutez l'événement 'Paint' pour chaque pictureBox
    • sélectionner un objet dans le 'designer'
    • choisissez l'onglet 'propriétés' (ou faites un clic droit et choisissez dans le menu contextuel)
    • sélectionnez le bouton des événements (petit éclair)
    • double-cliquez dans le champ vide à droite de l'événement 'Paint'
  4. Ajoutez le code suivant à la fonction 'load' du formulaire principal (s'il n'a pas déjà été ajouté, utilisez l'approche décrite à l'étape 3 et sélectionnez 'on load' plutôt que 'Paint')

=

private void cFeedback_Form_Load(object sender, EventArgs e)
{
    ...
    // Ensure that it is setup with transparent background
    foreground_pictureBox.BackColor = Color.Transparent;

    // Assign it's 'background'
    foreground_pictureBox.Parent = background_pictureBox;
    ...
}

5 Dans l'appel 'Paint' pour le 'background_pictureBox':

=

private void background_pictureBox_Paint(object sender, PaintEventArgs e)
{
    ...foreground_pictureBox_Paint(sender, e);
}

6 Dans l'appel 'foreground_pictureBox_Paint', ajoutez tous les appels graphiques que vous souhaitez afficher au premier plan. 

Ce sujet se répète dans plusieurs posts, il semble:

comment-faire-faire-picturebox-transparent

c-sharp-picturebox-fond-transparent-ne semble pas fonctionner

make-overlapping-picturebox-transparent-in-c-net

a-picturebox-problem

1
S. Arseneau

J'ai toujours constaté que je devais composer les images moi-même, en utilisant une seule boîte d'image ou un seul contrôle. Avoir deux boîtiers avec des parties transparentes n’a jamais fonctionné pour moi.

0
Charlie Salts