Traitement sur une Image

Résolu
Manu94600 Messages postés 107 Date d'inscription lundi 9 juin 2003 Statut Membre Dernière intervention 20 février 2008 - 4 avril 2006 à 13:45
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 - 4 avril 2006 à 18:33
Bonjour à tous,

Je cherche à remplacer une couleur dans un objet "Bitmap".
Par exemple, j'ai une image qui contient du rouge, je veux en fait que ce rouge soit transformer en une autre couleur.

Je me tourne vers vous car j'ai cherché un peu et j'ai pas trouvé et le truc c'est que je sais même pas par où commencer.

Merci d'avance pour votre aide.

Manu

15 réponses

MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
4 avril 2006 à 17:46
Vas faire un petit tour de Reflector pour voir comment agit la méthode Color.Equals() ;)
Du coup, je te conseil de la remplacer ton if par celui ci :


<HR>
if (cSource.ToArgb().Equals(
Color.Red.ToArgb()))
bitmap.SetPixel(x, y,
Color.FromArgb(
Color.Blue.R,
Color.Blue.G,
Color.Blue.B));

<HR>

Autrement, pour que ca aille plus vite, il faut utilisé du code non managé, ce qui implique activation de unsafe pour la compilation, et faire joujou avec les pointeurs



Mx
MVP C#
3
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
4 avril 2006 à 17:50
Tiens, voila une version non managée bien plus rapide


<HR>


public
static
void UnsafeChange(System.Drawing.
Bitmap bmp)
{
System.Drawing.Imaging.
BitmapData bitmapData = bmp.LockBits(
new System.Drawing.
Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.
ImageLockMode.ReadWrite, System.Drawing.Imaging.
PixelFormat.Format24bppRgb);

int scan = bitmapData.Stride;
System.
IntPtr Scan0 = bitmapData.Scan0;

unsafe
{

byte* p = (
byte*)(
void*)Scan0;

int nOffset = scan - bmp.Width * 3;

byte r;
// red
byte g;
// green
byte b;
// blue
for (
int y = 0; y < bmp.Height; ++y)
{

for (
int x = 0; x < bmp.Width; ++x)
{
b = p[0];
g = p[1];
r = p[2];
if(r 255 && g 0 & b == 0)
{
p[0] = 255;
p[1] = p[2] = 0;
}
p += 3;
}
p += nOffset;
}
}
bmp.UnlockBits(bitmapData);
}


<HR>

Y'a peut-etre une maniere plus élégante, mais ca fonctionne ;)



Mx
MVP C#
3
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
4 avril 2006 à 17:58
Avec Visual Studio, Il te suffit d'aller dans les propriétés de ton projet, et de cocher la petite case qui va bien qui autorise le code unsafe.



Mx
MVP C#
3
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
4 avril 2006 à 15:21
Salut,

Avec la méthode Bitmap.GetPixelet Bitmap.SetPixel, tu devrais pouvoir t'en sortir.
Par contre, comme c'est du code managé, ca risque d'etre tres tres lent.


Mx
MVP C#
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Manu94600 Messages postés 107 Date d'inscription lundi 9 juin 2003 Statut Membre Dernière intervention 20 février 2008
4 avril 2006 à 16:51
Désolé mais je débute avec cette objet.
Pourrait tu me dire comment on parcourt les pixel du Bitmap stp.

Merci

Manu
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
4 avril 2006 à 17:00
En fait, il te suffit de faire 2 boucles for imbriquées, qui bouclent sur la hauteur et la largeur de ton objet bitmap.
Tu trouveras un exemple ici. Tu n'as plus qu'a adapter pour faire en sorte que si la Couleur retournée par GetPixel = la couleur rouge, tu la remplaces via un SetPixel par la couleur souhaitée





Mx
MVP C#
0
Manu94600 Messages postés 107 Date d'inscription lundi 9 juin 2003 Statut Membre Dernière intervention 20 février 2008
4 avril 2006 à 17:18
Voici mon code.


Color cSource;



Bitmap bitmap =
new
Bitmap(
this.Width,
this.Height,
PixelFormat.Format32bppArgb);



this.DrawToBitmap(bitmap,
new
Rectangle(
new
Point(0, 0),
this.Size));



for (
int y = 0; y < bitmap.Height; y++)
{

for (
int x = 0; x < bitmap.Width; x++)
{
cSource = bitmap.GetPixel(x, y);
cSource =
Color.FromArgb(cSource.R, cSource.G, cSource.B);


if (cSource.Equals(
Color.Red))
bitmap.SetPixel(x, y,
Color.FromArgb(
Color.Blue.R,
Color.Blue.G,
Color.Blue.B));
}
}





using (
Form f =
new
Form())
{
f.BackgroundImage = bitmap;
f.ClientSize = bitmap.Size;

f.ShowDialog();
}

Il devrait faire une capture d'ecran, une image bitmap, et ensuite si la couleur de la source est rouge alors il met le pixel en bleu.
Et ensuite afficher la capture dans une autre fenetre. Mais moi j'ai pas ça, j'ai la capture original avec le rouge au lieu du bleu.

Alors je comprends pas pourquoi, si tu as une idée ??

Merci

Manu
0
Manu94600 Messages postés 107 Date d'inscription lundi 9 juin 2003 Statut Membre Dernière intervention 20 février 2008
4 avril 2006 à 17:24
Et aussi je voudrais savoir s'il y a un moyen plus rapide en même temps car tu m'as dit : ça risque d'être très très lent.

En fait je voudrais faire l'équivalent du pot de peinture sous paint ou autre logiciel.

Manu
0
Manu94600 Messages postés 107 Date d'inscription lundi 9 juin 2003 Statut Membre Dernière intervention 20 février 2008
4 avril 2006 à 17:50
Oula :) tu me parles de code nom managé :).
Je suis que débutant encore :).

Merci pour ton aide :).

Manu
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
4 avril 2006 à 17:53
Si t'as des gros traitements a faire, ca peut valoir le coup ;)



Mx
MVP C#
0
Manu94600 Messages postés 107 Date d'inscription lundi 9 juin 2003 Statut Membre Dernière intervention 20 février 2008
4 avril 2006 à 17:56
J'ai une erreur lors de la compilation :


Du code unsafe ne peut apparaitre qu'en cas de compilation avec /unsafe.


Tu as une idée ?? J'ai fait copier/coller de ton code.

Manu
0
Manu94600 Messages postés 107 Date d'inscription lundi 9 juin 2003 Statut Membre Dernière intervention 20 février 2008
4 avril 2006 à 18:14
Merci bcp ça marche. :)
La différence est minim quand même.

Manu
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
4 avril 2006 à 18:30
Essaie avec une fenetre en 1024 * 768, la différence sera + que minime



Mx
MVP C#
0
Manu94600 Messages postés 107 Date d'inscription lundi 9 juin 2003 Statut Membre Dernière intervention 20 février 2008
4 avril 2006 à 18:31
Surement :).

Merci pour ton aide.
@+

Manu
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
4 avril 2006 à 18:33
y'a pas de quoi



Mx
MVP C#
0
Rejoignez-nous