FILTRES ET MANIPULATION D'IMAGES EN UTILISANT LOCKBITS ET DES POINTEURS

cs_yoannd Messages postés 305 Date d'inscription lundi 7 janvier 2002 Statut Membre Dernière intervention 10 août 2011 - 9 déc. 2004 à 18:47
billegate2006 Messages postés 2 Date d'inscription mercredi 17 janvier 2007 Statut Membre Dernière intervention 1 avril 2008 - 1 avril 2008 à 16:31
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/28087-filtres-et-manipulation-d-images-en-utilisant-lockbits-et-des-pointeurs

billegate2006 Messages postés 2 Date d'inscription mercredi 17 janvier 2007 Statut Membre Dernière intervention 1 avril 2008
1 avril 2008 à 16:31
Bonjour,
Je veux juste vous poser une question concernant le traitement d'images, bon je veux mettre une bar de zoom sur une image mais il faut quelle soit transparente comme la boussole du google earth, merci de votre reponse.
phoenikz Messages postés 2 Date d'inscription mardi 8 janvier 2008 Statut Membre Dernière intervention 17 avril 2008
5 mars 2008 à 08:37
J'ai réalisé un programme de traitement d'image à partir d'une webcam et ton code m'a énormément aidé pour passer en noir et blanc et compté les pixels de certaines couleurs, bref un grand merci (enfin bon là j'ai 4 ans de retard mais c'est pas grave)
olixelle Messages postés 506 Date d'inscription vendredi 30 juillet 2004 Statut Membre Dernière intervention 3 mars 2008 2
13 déc. 2007 à 13:04
Salut,

je ne connaissais le mode unsage qu'en théorie, j'en ai eu besoin récement donc je me suis très largement inspiré de ton code pour comprendre le principe et le mettre en application donc merci :)

Remarque: Si vous souahitez gérer la transparence des png, passez en Format32bppARgb et remplacez les 3 par des 4 lors de la copie des pixels (une constante aurait été bienvenue)

en tout cas merci :)
farias46 Messages postés 9 Date d'inscription lundi 29 janvier 2007 Statut Membre Dernière intervention 14 octobre 2008
13 févr. 2007 à 10:37
Monstrueusement efficace !!! J'ai commencé le C# il y a 2 semaines environ et j'ai été très déçu par les performances de celui-ci sur les traitements d'images. En effet j'utilisais la méthode "managed" c'est-à-dire avec les GetPixel et SetPixel. J'arrivais à plus de 14sec pour parcourir une image de 800x600... celà uniquement pour passer celle-ci en négatif!
Avec le mode "unsafe", sur une belle image de la lune avec une petite résolution de 5900x3100 siouplé :-) tous mes filtres prennent maxi 3sec !
Un grand merci à toi pour ce joli code qui m'a fait découvrir la puissance des pointeurs ;-)!
Equinox84 Messages postés 63 Date d'inscription lundi 2 février 2004 Statut Membre Dernière intervention 19 mai 2010
21 juil. 2006 à 10:33
Salut !

Merci pour ton code, il m'a permis d'inverser la couleur de mes graphiques avant l'impression, c'est tres pratique pour économiser le noir !
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
26 mars 2006 à 19:20
Salut à nouveau,
Je me suis inspiré de ton code pour optimiser une déformation d'image (pour faire de l'assemblage horizontal de photo). C'est vrai que c'est nettement plus efficace. Merci beaucoup.
cs_Warny Messages postés 473 Date d'inscription mercredi 7 août 2002 Statut Membre Dernière intervention 10 juin 2015
26 mars 2006 à 18:00
pour le fonction(i++) et le fonction(++i) le dotnet le compile en...
fonction(i); i = i+1;
et
i=i+1; fonction(i);
respectivement,
donc pour la vitesse, j'ai un doute ;)
kamal101 Messages postés 12 Date d'inscription samedi 24 janvier 2004 Statut Membre Dernière intervention 22 mars 2007
17 nov. 2005 à 21:44
Est-ce qu'il y a quelqu'un qui sait comment faire en c# la reconnaissance de forme. Je veux trouver des mini-cercles ronds dans une image et les mettre par exemple en noir. Est-ce qu'il y a une librairie pour ça ?
li9 Messages postés 57 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 11 septembre 2008 1
11 déc. 2004 à 09:41
Salut galinace,
on peut aussi utiliser les fonction "GetPixel()" et "SetPixel()" de la classe Bitmap pour travailler les pixels.
mais ces méthodes sont "très" lentes par rapport à l'utilisation de pointeurs.
Sur MSDN il y a un article interressant là dessus.
l'auteur y écrit qu'en Managed Code (getpixel,setpixel) son filtre Grayscale s'applique en 14sec. (enormement long mdr) , en Unmanaged (pointeurs) : 0.52sec ; )

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp11152001.asp

par contre je vois pas trop ce que tu as fais pour ton test entre Managed et Unmanaged , tu extraits ton bitmap de 2 manieres differente et tu lui appliques mon filtre ? o_o

Sinon mon avis général sur la question c'est que l'étude des pointeurs va me permettre beaucoup de choses impossible à faire en managed code ^^"

wallou

++
cs_galinace Messages postés 2 Date d'inscription mardi 15 avril 2003 Statut Membre Dernière intervention 11 décembre 2004
11 déc. 2004 à 00:53
Re ....

Je viens de réaliser quelques tests entre ta methode et celle consistant à extraire le graphics du bitmap et travailler directement dessus.

Je me suis permis de modifier un peu ton source afin de laisser la possibilité d'importer une image et par suite remplacer celle par défaut. J'importe une bitmap de taille importante (105 Mo) afin de voir les temps de calculs et la mémoire prise (je suis sur un XP2000+ à 512 DDR).

L'application d'un filtre selon ta methode prend environ 6 à 7 secondes à pleine puissance (je parle ici de travail sans effet mémoire pour la possibilité d'annulation afin de ne pas être inflencé par des éventuel swappages).

La même opération effectuée sur une bitmap par extraction du graphics prends exactement le même temps.

Tout ceci pour pauser la question de l'utilité du mode "unsafe". C'est effectivement une question qui me tracasse pas mal car d'une part, le mode managé permet une certaine "sécurité" du code mais est sensé ralentir quelque peut l'exécution. Malheureusement pour moi, chaque exemple que je peux tester ne me permet pas réellement de trancher sur un mode plutôt que l'autre.

Pourrais tu m'éclarrer sur ton choix (travail en mode unsafe) et ton avis général sur la question ???

D'avance encore merci
cs_galinace Messages postés 2 Date d'inscription mardi 15 avril 2003 Statut Membre Dernière intervention 11 décembre 2004
11 déc. 2004 à 00:15
Bonjour,

Je viens de lire ton poste et ta methode me parrait effectivement intéressante.

J'aurais aimé avoir une sorte de comparatif ou tout du moins d'ordre d'idée concernant la différence de rapidité d'exécution entre le principe que tu décris (parcourt par pointeur etc) et le fait de rester en mode managé et dessiner la bitmap en passant par un objet "graphics".

Effectivement je ne parle pas là de modification de luminosité ou autre mais bien de dessin à proprement parler d'une bitmap. Je sais que ce n'est pas directement le sujet mais un rapport tout de même étroit m'a poussé a écrire ce poste.

Merci d'avance pour ta réponse
cs_yoannd Messages postés 305 Date d'inscription lundi 7 janvier 2002 Statut Membre Dernière intervention 10 août 2011 7
10 déc. 2004 à 09:32
Putain là ouais, ca marche, et c'est nikel !
tu viens de donner pas mal de valeur à ta source là, d'un coup ! ben bravo, je trouve ca extra !
li9 Messages postés 57 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 11 septembre 2008 1
9 déc. 2004 à 21:18
Merci pour ton commentaire.
Effectivement , y avait quelques fautes mdr ....
J'ai tout corrigé (je pense .... ) et j'ai rajouté un zip avec quelques filtres supplémentaires pour me faire pardonner v( ^_^ )v .

J'ai voulu faire le chaud et tout taper de tête en postant ma source , c'est à cause de ça qu'y avait autant de fautes ....j'aurais dû faire un vieux copier/coller xD

C'est vrai que j'aurais dû parler des namespaces ,
Je m'en excuse !!

Pour "++i" ou "i++" t'as peut être raison, je pensait avoir vu ça dans la version de msdn fournit dans vs.net ... à vérifier ...
et pour la déclar. du pointeur moi les 2 passent niquel o_O , mais je me sert que de "(byte*)(void*)scan0"
Réessayes avec la source de mon zip. : /
on sait jamais ...

Ciao
cs_yoannd Messages postés 305 Date d'inscription lundi 7 janvier 2002 Statut Membre Dernière intervention 10 août 2011 7
9 déc. 2004 à 18:52
Ha oui, dernier truc, tu écris ceci dans ton code:
byte* p = (byte*)(void*)scan0;
//on peut aussi écrire "byte* p = (byte*)scan0.ToPointer();"

Ben moi, il y a que
byte* p = (byte*)scan0.ToPointer();
... qui passe à la compilation.
cs_yoannd Messages postés 305 Date d'inscription lundi 7 janvier 2002 Statut Membre Dernière intervention 10 août 2011 7
9 déc. 2004 à 18:47
Alors, les erreurs, il y en a quelques une, en effet, mais rien de bien méchant :

Bitamp bmp = new Bitmap(ImageOrigine,ImageOrigin.Width,ImageOrigin.Height);

on préferrera déclarer un Bitmap plutot qu'un Bitamp et le vairable ImageOrigin n'existe pas, il faut écrire ImageOrigine

Je suppose que tu as voulu écrire ca
int nOffset = scanline-bmp.Width*3;

...à la place de
int nOffset = stride-bmp.Width*3;

Par contre, tu écris aussi ceci :
Image imgOut = Image.FromHBitmap(newBmp.GetHBitmap());
mais mon compilo ne trouve pas les fonction FromHBitmap et GetHBitmap. Est-ce qu'il me manque des using ? Ha non, je viens de voir que FromHbitmap avec un b minuscule fonctionnait, ainsi que GetHbitmap.

D'ailleurs, ce serait pas mal de les indiquer. Il me semble qu'il nous faut ici les using suivants :
using System.Drawing;
using System.Drawing.Imaging;

De plus, il ne me semble jamais avoir entendu que ++x et x++ étaient différents en terme de rapidité, mais la différence, c'est que si j'écris :
x = 3;
Console.WriteLine("" + (x++));
Ca m'affiche 3, puis ca incrémente de 1 la valeur x, alors que si j'écris :
Console.WriteLine("" + (++x));
ben ca incrémente de un la valeur x puis ca affiche 3+1, soit 4.

Bon, passons sur ceci, ce qui m'embète un peu plus, c'est que j'ai testé ce code, et ca me donne une image qui ne contient que des bandes grises et noires, bref, donc voila, heuuu, je crois qu'il y a un bug. En tout cas, c'est tout de même un contribution et ca peut peut-être aider quelqu'un, c'est le point positif de la chose. Mais c'est vrai qu'un petit zip, ca aurait été cool.