Les mystères de la représentation mémoire d'un objet Bitmap [C#] - C#/.NET managed - Programmation
Marsh Posté le 01-06-2006 à 23:19:01
Pour preuve qu'en faisant "total n'importe quoi" ça marche :
Marsh Posté le 02-06-2006 à 15:46:04
ben ça m'ennuie quand je comprends pas. surtout que là, j'ai besoin de comprendre ce que ça fait, parceque je vais devoir modifier le truc...
et déjà en comprenant ce que je fais, je m'en sors pas, mais alors là, c'est le pompom
Marsh Posté le 02-06-2006 à 16:15:21
Je serais toi, je rajouterai des variables pour stocker les valeurs calculées.
Ca peut optimiser un pti peu tes boucles, et ça te permettra sans doute de mieux comprendre.
Paske les for(int x = j * sHeight; x < (j + 1) * sHeight; x++) c'est assez inbitable
Marsh Posté le 02-06-2006 à 16:45:34
Euh... au départ, sHeight n'existait pas, c'était :
(j + 1) * (ori.Height / ((ori.Height * nbCols) / ori.Width))
Là, ouais, c'était imbittable
Marsh Posté le 08-06-2006 à 12:01:54
Voilà un bout de code qui peut ptet t'intéresser :
Code :
|
Marsh Posté le 08-06-2006 à 12:55:14
1/ pkoi le +4 ?
2/ ouais, mais justement, si tu regardes mon code, mes interrogations sont en fonction du schéma que tu as posté : à moins que je me sois complètement planté dans le nommage de mes variables (possible) j'ai une incohérence complète : je bouge mon pointeur à partir de la largeur, mais ce sont des colonnes que je récupère, et non ds lignes. du coup, je lis beaucoup trop de fois une taille trop grande (donc ça devrait déborder) et pourtant je récupère bien mon image, alors qu'en toute logique elle devrait être complètement déterriorrée (problèmes d'offsets). hors ça marche
Marsh Posté le 08-06-2006 à 13:58:51
1)
2) Ya plein de truc que je capte pas trop dans ton code :
Ca par exemple :
int nbRows = (ori.Height * nbCols) / ori.Width;
Et ca ? ca te file le nombre de pixels (zone de padding compris, ce qui n'a pas de sens) mais pas le nombre de bytes
int byteCount = bData.Stride * ori.Height;
Marsh Posté le 08-06-2006 à 14:13:17
Code :
|
Moi je fais pas le +4 et ça marche quand même
Et pourtant, y'a pas 4 d'écart entre le width et le height de mon image
Marsh Posté le 08-06-2006 à 14:17:04
Xavier_OM a écrit : |
Parceque je découpe mon image en petits rectangles avant le traitement.
(à la base, je vais faire des traîtements sur ces rectangles de découpe).
Là, nbCols est mettons 10.
Vu que je veux des rectangles "carrés", je récupère nbRows en fonction de la largeur et de la hauteur (ratio).
C'est vrai que mes boucles imbriquées ne sont pas terrible pour aider à la compréhesion...
En fait, je recopie l'image par petits rectangles, et non pas de façon séquencielle.
Marsh Posté le 08-06-2006 à 14:17:08
Arjuna a écrit :
|
Je fais pas +4 hein
La longueur d'une ligne en bytes c'est stride, la longueur de mon image en pixels c'est width, donc en bytes pour du 32bits c'est 4*width
D'où un padding de stride - 4*width
D'où j'avance de cette quantité pour me placer sur la ligne suivante
Marsh Posté le 08-06-2006 à 14:18:47
Sinon, je ne sais pas d'où tu sors ce padding en fait.
Le "bytesCount" (et tout le bloc qui va avec) c'est un copy/paste à partir d'un site style "csharpcorner".
je me demande même si j'ai pas vu le même truc sur la MSDN.
PS: je suis en .NET 2.0 ici. Au cas où ça changer d'une version à l'autre (ce serait bien con mais bon )
Marsh Posté le 08-06-2006 à 14:20:30
D'ailleurs, en re-regardant ton graph, c'est toi qu'est pas logique.
stride = (with * nbBytespp) + padding
donc stride * height est bel et bien égal au nombre de bytes correspondant à l'image mémoire entière du bitmap... y'a pas à tortiller à ce niveau...
du coup, en bon français : (pour une image 24 bits)
|
Marsh Posté le 08-06-2006 à 14:25:23
MSDN :
"The stride is the width of a single row of pixels (a scan line), rounded up to a four-byte boundary. The stride is always greater than or equal to the actual pixel width. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up."
désolé mais faut lire la doc hein
Marsh Posté le 08-06-2006 à 14:26:19
ben oui, donc les 4 pixels ne sont pas "en plus" du stride, il sont déjà dans le stride...
dans ton exemple de code de là-haut, y'a une erreur avec le 4...
Marsh Posté le 08-06-2006 à 14:27:11
correction : nan, y'a pas d'erreur. juste IE 7 béta 2 qui écrit la balise "code" trop petit : je voyais un + 4 et non un * 4
* 4, je suis d'accord
Marsh Posté le 08-06-2006 à 14:27:52
Arjuna a écrit : ben oui, donc les 4 pixels ne sont pas "en plus" du stride, il sont déjà dans le stride... |
j'abandonne, visiblement tu ne sais pas lire
Marsh Posté le 08-06-2006 à 14:29:29
Xavier_OM a écrit : MSDN : |
up to, ça veut dire "jusqu'à" donc c'est pas forcément 4.
mais vu que c'est pas un + mais un * qu'il y a dans ton code, je suis d'accord. moi je croyais que tu ajoutait la taille du stride + 4 dans l'offset
Marsh Posté le 08-06-2006 à 14:30:02
Xavier_OM a écrit : j'abandonne, visiblement tu ne sais pas lire |
c'est toi qui veut pas comprendre que IE7b2 est trop con pour rendre lisible la balise CODE
Marsh Posté le 08-06-2006 à 14:30:18
Arjuna a écrit : up to, ça veut dire "jusqu'à" donc c'est pas forcément 4. |
change de browser alors
Marsh Posté le 01-06-2006 à 23:11:09
J'en ai chié comme un rat dépressif mort pendant 3 heures pour remplacer "GetPixel()" qui est très lent par le parcours en mémoire d'un array de byte correspondant aux données brutes d'un objet Bitmap...
Seulement, j'ai fini par trouver la solution "par l'oppération du saint esprit", et je ne comprends pas :
- pkoi ça plante pas (en toute logique, je devrais avoir un dépassement mémoire)
- pkoi ça marche (que ça plante pas... là la limite... mais que ça donne le bon résultat, là c'est moi qui fait un stack overflow )
- pkoi quand je lit n'importe comment de manière anarchique dans le tableau, j'ai que des couleurs grises, alors que par cette oppération foireusement miraculeuse, ça me donne des couleurs...
Des suggestions ?
=> Pour le moment, ça ne fait que pixeliser l'image. Je recopie une image d'une picturebox (objet ori) vers l'image d'un autre picture box en passant par un Graphics (objet g). J'en profite pour faire la moyenne des couleurs dans des rectangles de découpe, puis je dessine un rectangle de la même taille avec la couleur moyenne dans la destination (le but après, ça va être de modifier cet affichage des rectangles pour faire autre chose, donc me sortez pas "laMethodePixeliseQuiTue()", elle ne me servira à rien