Transparence dans une picture box

johnnous Messages postés 100 Date d'inscription jeudi 3 mars 2005 Statut Membre Dernière intervention 24 mai 2013 - 11 mars 2010 à 12:36
johnnous Messages postés 100 Date d'inscription jeudi 3 mars 2005 Statut Membre Dernière intervention 24 mai 2013 - 16 mars 2010 à 19:48
bonjour
j'ai un soucis
je fait une rotation d'une picturebox cela marche bien
mais je n'arrive à avoir la couleur transparente
private void RotationPictureBox(int AngleDegre,PictureBox MyPictureBox)
{
Graphics G;

//on mémorise la longueur de l'image
//je pars de l'hypothèse que j'utilise une image carré

float Largeur = MyPictureBox.Width;
float Hauteur = MyPictureBox.Height;

//on mémorise l'image présente dans la picture box
Image IMG = MyPictureBox.Image;

//définition de la picturebox comme espace de dessin
G = MyPictureBox.CreateGraphics();

//on efface
G.Clear(this.BackColor);
// G.Clear(Color.Transparent );
//on transforme l'angle en radians
double Angle = (AngleDegre / 180.0) * Math.PI;

float Largeur2 = Largeur;
float Hauteur2 = Hauteur;
//on calcule les nouvelles coord X et Y de l'image
float PosX =(float)( Math.Sqrt(2)* (Largeur2)* Math.Sin(Angle / 2) * Math.Cos(Math.PI / 4 + Angle / 2));
float PosY = (float)( -Math.Sqrt(2) * (Largeur2) * Math.Sin(Angle / 2) * Math.Cos(Math.PI / 4 - Angle / 2));
PosX = PosX + MyPictureBox.Width / 2 - MyPictureBox.Image.Width / 2;
PosY = PosY + MyPictureBox.Height / 2 - MyPictureBox.Image.Height / 2;
//on fait la rotation
G.RotateTransform(AngleDegre);
G.DrawImage(IMG, PosX, PosY, MyPictureBox.Image.Width, MyPictureBox.Image.Height);
G.Dispose();

}

c'est le G.Clear(this.BackColor); qui m'embete
et si je met G.Clear(Color.Transparent ); j'ai ma picturebox en noir

private void button11_Click(object sender, EventArgs e)
{
PicBoxP1.Parent = pictureBox2;
PicBoxP1.Left = 30;
PicBoxP1.Top = 20;
PicBoxP1.BringToFront();
}
// numericUpDown
private void angle_ValueChanged(object sender, System.EventArgs e)
{
RotationPictureBox((int)angle.Value, PicBoxP1);
}

quelqu'un peux m'aidder
merci


Jean louis

4 réponses

cs_Robert33 Messages postés 834 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 14 janvier 2017 33
13 mars 2010 à 19:45
Bonjour
C'est un peu normal la gestion de la couleur transparente n'est pa parfaite. car lorsque un control est dessiné, la couleur transparente va être remplacée par la couleur du fond de la forme, si un autre control se trouve entre le fond de la forme et le control en cours il sera masqué.

le seul moyen est de dessiner toi même l'image.
Dans ton exemple, tu veux incruster un image sur une Picture box "parente".
je te propose la modification suivante de ton code:
L'idée est de mémoriser l'incrustation et la rotation dans la pictureBox à incrustée et de la cacher, puis on surcharge la methode Paint de la pictureBox mère, et une fois qu'elle a été dessiné on redessine par dessus l'incrustation, en tenant compte des parametres de rotation mémorisés.

code:
Classe de mémorisation des parametres de rotation et de position
class  RotationInfo
{
    public float  posx;
    public float  posy;
    public int angleDegre;
    public RotationInfo(int angleDegre, float  posx, float  posy)
    {
        this.posx = posx;
        this.posy = posy;
        this.angleDegre = angleDegre;
    }
}

Modification de ta méthode "RotationPictureBox"
on ne fait que calculer et on stocke l'info dans la picturebox à incruster
//Calcul la rotation et range tout dans le tag de la picturebox
private void RotationPictureBox(int AngleDegre, PictureBox MyPictureBox)
{

    float Largeur = MyPictureBox.Width;
    float Hauteur = MyPictureBox.Height;

    //on transforme l'angle en radians 
    double Angle = (AngleDegre / 180.0) * Math.PI;

    float Largeur2 = Largeur;
    float Hauteur2 = Hauteur;
    //on calcule les nouvelles coord X et Y de l'image 
    float PosX = (float)(Math.Sqrt(2) * (Largeur2) * Math.Sin(Angle / 2) * Math.Cos(Math.PI / 4 + Angle / 2));
    float PosY = (float)(-Math.Sqrt(2) * (Largeur2) * Math.Sin(Angle / 2) * Math.Cos(Math.PI / 4 - Angle / 2));
    PosX = PosX + MyPictureBox.Width / 2 - MyPictureBox.Image.Width / 2;
    PosY = PosY + MyPictureBox.Height / 2 - MyPictureBox.Image.Height / 2;
    MyPictureBox.Tag = new RotationInfo(AngleDegre,PosX,PosY);

}

Modification de tes méthodes
        
private void button1_Click(object sender, EventArgs e)
{
    RotationPictureBox(0, PicBoxP1);//calcul de la postion de base
    PicBoxP1.Hide(); // on cache la picture box à incruster
    pictureBox2.Invalidate(); //force le rafraichissement de la picture box mère
}

private void angle_ValueChanged(object sender, EventArgs e)
{
    RotationPictureBox((int)angle.Value, PicBoxP1);
    pictureBox2.Invalidate();//force le rafraichissement de la picture box mère

}

Il ne manque que la surchage de la methode Paint de la picture box mère
attention pense à mettre
this.pictureBox2.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox2_Paint);
quelquepart ...

private void pictureBox2_Paint(object sender, PaintEventArgs e)
{
    //on récupere les information pour la PicBox1
    RotationInfo rotationInfo= PicBoxP1.Tag as RotationInfo;
    if (rotationInfo != null)
    {
        e.Graphics.RotateTransform(rotationInfo.angleDegre);
        e.Graphics.DrawImage(PicBoxP1.Image, rotationInfo.posx, rotationInfo.posy, PicBoxP1.Image.Width, PicBoxP1.Image.Height);
    }

}


On peut imaginer avoir autant de picBox à incruster que l'on veut.
à toi de définir l'ordre d'apparition dans la méthode paint.
si la picturebox mère est tres grande tu peux avoir un probleme de performance et de clignotement, il faut alors modifier l'odre Invalidate(...) et passer en paramètre seulement la région que tu veux redessiner.

amuse-toi bien.
C# is amazing, enjoy it!
0
johnnous Messages postés 100 Date d'inscription jeudi 3 mars 2005 Statut Membre Dernière intervention 24 mai 2013
15 mars 2010 à 14:51
Merci
ça l'air de bien marche par contre j'aimerais avoir plusiseurs picturebox et pouvoir les déplacer c'est possible ?


Jean louis
0
cs_Robert33 Messages postés 834 Date d'inscription samedi 15 novembre 2008 Statut Membre Dernière intervention 14 janvier 2017 33
16 mars 2010 à 18:14
hehe,

pour plusieurs, essaie de te creer une list
genre List PictbList = new List();
dans laquelle tu range toute tes picturebox
ensuite, dans la methode Paint tu remplace PicBoxP1 par une boucle sur toutes les pictures box genre
foreach (PictureBox PicBox in PictbList )
{
...
}

pour les selectionner, il faut detecter le click de la souris sur la pcitureBox mere et regarder si cela peut correspondre à une des picture box de la liste.
restera plus qu'a modifier les proprietées posx et posy de l'objet rotationInfo.

si tu n'y arrives pas, repost un message.
Bon code


C# is amazing, enjoy it!
0
johnnous Messages postés 100 Date d'inscription jeudi 3 mars 2005 Statut Membre Dernière intervention 24 mai 2013
16 mars 2010 à 19:48
bonsoir
je te remercie de ta réponse, je pense que tu as raison mais je n'arrive pas à le mettre en place
car il faut que j'arrive a detecte sur quelle image j'ai cliqué afin de la selectionner et de pouvoir ensuite la faire bouger et tourner, si tu avais un exemple un plus préci (je ne suis pas très doué)

Jean louis
0
Rejoignez-nous