Soyez le premier à donner votre avis sur cette source.
Vue 13 988 fois - Téléchargée 1 083 fois
//***************************************************************************** // GetBmpSize : récupère la taille d'un bitmap. // entrée : hBmp : bitmap dont on souhaite récupérer la taille. // retour : taille du bitmap spécifié. //***************************************************************************** SIZE GetBmpSize(HBITMAP hBmp) { // récupération des informations sur le bitmap BITMAP bmpInfo; GetObject(hBmp, sizeof(bmpInfo), &bmpInfo); // taille SIZE size; size.cx = bmpInfo.bmWidth; size.cy = bmpInfo.bmHeight; return size; } //***************************************************************************** // GetBmpData : récupère les données (pixels) d'un bitmap. // entrée : hdc : DC à utiliser pour les appels aux fonctions API. // hBmp : bitmap source. // retour : données du bitmap (à libérer par VirtualFree) ou NULL en cas // d'erreur. //----------------------------------------------------------------------------- // Remarques : - les données sont récupéres en 32 bits par pixels (4octets) // afin d'éviter d'avoir à rajouter du padding pour aligner les // lignes sur 4 octets. // - les bitmaps top-down ne sont pas gérés. // - les pixels sont stockées par ligne à partir du bas du bitmap // (bottum-up). //***************************************************************************** LPVOID GetBmpData(HDC hdc, HBITMAP hBmp) { // taille du bitmap, si bitmap top-down on renvoi NULL SIZE sizeBmp = GetBmpSize(hBmp); if(sizeBmp.cy < 0) return NULL; // allocation mémoire (on va récupérer en 32 bits par pixel) DWORD dwSize = 4*sizeBmp.cx*sizeBmp.cy; LPVOID lpMem = VirtualAlloc(NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); if(lpMem == NULL) return NULL; // initialisation structure BITMAPINFO BITMAPINFO bi; ZeroMemory(&bi, sizeof(BITMAPINFO)); bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biWidth = sizeBmp.cx; bi.bmiHeader.biHeight = sizeBmp.cy; bi.bmiHeader.biCompression = BI_RGB; // récupération bits int nResult = GetDIBits(hdc, hBmp, 0, sizeBmp.cy, lpMem, &bi, DIB_RGB_COLORS); // si tout c'est bien passé if(nResult != 0) return lpMem; // erreur, libération de la mémoire VirtualFree(lpMem, 0, MEM_RELEASE); return NULL; } //***************************************************************************** // RotateBmp : effectue une rotation d'un bitmap. // entrée : hdc : DC à utiliser pour les appels aux fonctions API. // hBmpSrc : bitmap source. // nAngle : angle de rotation, en degré, dans le sens trigo (inverse // horaire. Seules les valeurs 0, 90, 180 et 270 sont // valides. // retour : bitmap avec la rotation demandée ou NULL en cas d'erreur. //***************************************************************************** HBITMAP RotateBmp(HDC hdc, HBITMAP hBmpSrc, int nAngle) { // nAngle doit être 0, 90, 180 ou 270 if(nAngle != 0 && nAngle != 90 && nAngle != 180 && nAngle != 270) return NULL; // taille et données du bitmap source SIZE sizeSrc = GetBmpSize(hBmpSrc); LPVOID lpDataSrc = GetBmpData(hdc, hBmpSrc); if(lpDataSrc == NULL) return NULL; // taille du bitmap de destination SIZE sizeDst = sizeSrc; if(nAngle == 90 || nAngle == 270) { sizeDst.cx = sizeSrc.cy; sizeDst.cy = sizeSrc.cx; } // allocation mémoire pour le bitmap de destination (32 bits par pixel) DWORD dwSize = 4*sizeDst.cx*sizeDst.cy; LPVOID lpDataDst = VirtualAlloc(NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); if(lpDataDst == NULL) { VirtualFree(lpDataSrc, 0, MEM_RELEASE); return NULL; } // affectation des bits for(int xSrc = 0; xSrc < sizeSrc.cx; xSrc++) { for(int ySrc = 0; ySrc < sizeSrc.cy; ySrc++) { // pixel de destination : int xDst, yDst; switch(nAngle) { case 0 : xDst = xSrc; yDst = ySrc; break; case 90 : xDst = sizeSrc.cy-ySrc-1; yDst = xSrc; break; case 180: xDst = sizeSrc.cx-xSrc-1; yDst = sizeSrc.cy-ySrc-1; break; case 270: xDst = ySrc; yDst = sizeSrc.cx-xSrc-1; break; } // affectation du pixels (32 bits = 4 octets = 1 DWORD) LPDWORD lpSrc = (LPDWORD)lpDataSrc+sizeSrc.cx*ySrc+xSrc; LPDWORD lpDst = (LPDWORD)lpDataDst+sizeDst.cx*yDst+xDst;
1 oct. 2004 à 23:23
à la fin, il faut soit recréer un bitmap soit affecter les données avec SetDIBits
1 oct. 2004 à 19:55
je vai essayer de mediter la dessus !
1 oct. 2004 à 19:38
ds ce cas tu appelles ton tableau array. mais ds ton prog, quel est le nom du tableau ?
1 oct. 2004 à 16:22
Dans mon exemple, je récupère les données avec des pixels codés sur 32 bits (c'est plus simple à gérer). C'est la fonction GetBitmapData() qui s'en charge
Ensuite, il faut savoir qu'un bitmap est stocker ligne par ligne en commançant par le bas (bitmap Bottum-Up). Il existe la convention inverse (Top-Down), mais c'est plus rare. sur chaque ligne, les pixels sont stockés de gauche à droite sur le nombre de bits demandés.
Le point important c'est que la taille d'une ligne en octets doit être multiple de 4 octets=32bits pour des raisons d'alignement de la mémoier (d'où le 32 bits par pixel pour simplifier).
donc on récupère un tableau d'octet de taille 4*Hauteur*Largeur :
BYTE array[4*hauteur, largeur].
les données du pixel (x,y) avec la convention habituelle x vers la droite et y vers le bas, sont stockées là:
array[((hauteur-y-1)*largeur+x)*4];
array[((hauteur-y-1)*largeur+x)*4+1];
array[((hauteur-y-1)*largeur+x)*4+2];
array[((hauteur-y-1)*largeur+x)*4+3];
le premier octet est la composante bleue
le deuxième la composante verte.
la troisième la composante rouge.
la quatrième est à 0.
30 sept. 2004 à 21:55
Tu pourrai me dire avec un ptit exemple comment modifier un HBITMAP en mettant ( par exemple ) un pixel rouge au coordone (5,5) de celui ci Avant qu'il soit afficher bien sure.
utiliser SetPixel() je sais faire !.
merci !
salut et bonne prog !
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.