begin process at 2010 03 18 06:33:27
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Graphique

 > ROTATION BITMAP

ROTATION BITMAP


 Information sur la source

Note :
9,5 / 10 - par 2 personnes
9,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Graphique Niveau :Débutant Date de création :23/06/2004 Vu / téléchargé :9 136 / 825

Auteur : ymca2003

Ecrire un message privé
Commentaire sur cette source (7)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Code permettant d'effectuer une rotation sur un HBITMAP de 0°, 90°, 180° ou 270°.

Source

  • //*****************************************************************************
  • // 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;
  • *lpDst = *lpSrc;
  • }
  • }
  • // initialisation structure BITMAPINFO pour le bitmap de destination
  • BITMAPINFO bi;
  • ZeroMemory(&bi, sizeof(BITMAPINFO));
  • bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  • bi.bmiHeader.biPlanes = 1;
  • bi.bmiHeader.biBitCount = 32;
  • bi.bmiHeader.biWidth = sizeDst.cx;
  • bi.bmiHeader.biHeight = sizeDst.cy;
  • bi.bmiHeader.biCompression = BI_RGB;
  • // création du bitmap de destination
  • HBITMAP hBmpDst = CreateDIBitmap(hdc, &bi.bmiHeader, CBM_INIT, lpDataDst,
  • &bi, DIB_RGB_COLORS);
  • // libération mémoire
  • VirtualFree(lpDataSrc, 0, MEM_RELEASE);
  • VirtualFree(lpDataDst, 0, MEM_RELEASE);
  • // retour
  • return hBmpDst;
  • }
//*****************************************************************************
// 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;
			*lpDst = *lpSrc;
		}
	}

	// initialisation structure BITMAPINFO pour le bitmap de destination
	BITMAPINFO bi;
	ZeroMemory(&bi, sizeof(BITMAPINFO));
	bi.bmiHeader.biSize			= sizeof(BITMAPINFOHEADER);
	bi.bmiHeader.biPlanes		= 1;
	bi.bmiHeader.biBitCount		= 32;
	bi.bmiHeader.biWidth		= sizeDst.cx;
	bi.bmiHeader.biHeight		= sizeDst.cy;
	bi.bmiHeader.biCompression	= BI_RGB;

	// création du bitmap de destination
	HBITMAP hBmpDst = CreateDIBitmap(hdc, &bi.bmiHeader, CBM_INIT, lpDataDst,
			&bi, DIB_RGB_COLORS);

	// libération mémoire
	VirtualFree(lpDataSrc, 0, MEM_RELEASE);
	VirtualFree(lpDataDst, 0, MEM_RELEASE);

	// retour
	return hBmpDst;
}


 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture SPLITTER API WIN32
Source avec Zip Source avec une capture UTILISATION DE LA LIB SHLWAPI.DLL (FONCTIONS DIVERSES SUR LE...
Source avec Zip Source avec une capture WIN32ACTIVEX : CONTENEUR DE CONTRÔLES ACTIVEX EN WIN32 (API ...
Source avec Zip Source avec une capture UTILISATION SPLITTER AVEC MFC
Source avec Zip Source avec une capture EXTRACTION DES ICONES DES EXÉCUTABLES (.EXE, .DLL), (VC++, W...

 Sources de la même categorie

Source avec Zip Source avec une capture VISUALISATION DES IMAGES EN 3D SANS OPENGL par Pistol_Pete
Source avec Zip Source avec une capture ANALYSE DE LA TEXTURE D'UNE IMAGE : FILTRE DE GABOR par Pistol_Pete
Source avec Zip Source avec une capture MONPPM : UN AFFICHEUR .PPM par pgl10
Source avec Zip MOTEUR 3D : CASTOR3D par dragonjoker59
Source avec Zip Source avec une capture VIEWER COMPLET POUR LE TRAITEMENT DE L'IMAGE : IMANALYSE par Pistol_Pete

Commentaires et avis

Commentaire de kisscool19812002 le 21/09/2004 13:40:11

comment accèder aux valeurs couleurs des pixels et les modifier ? comment enregistrer la bitmap ainsi construite dans un fichier bmp sur le dur ?? merci

Commentaire de ymca2003 le 22/09/2004 00:23:26

jette un oeil là
http://www.cppfrance.com/code.aspx?id=21052

Commentaire de Adeon le 30/09/2004 21:55:17

j'avoue que j'ai du mal a suivre ton code ( pourtant il est bien commente ! )

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 !

Commentaire de ymca2003 le 01/10/2004 16:22:49

tout d'abord, il faut récupérer les données du bitmap, c'est à dire récuprer la suite d'octets composant l'image, celle-ci étant représenter par des pixels codés sur 1, 4, 8, 24 ou 32 bits.

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.

Commentaire de Adeon le 01/10/2004 19:38:24

ok merci c'est sympa de t'occuper de moi.
ds ce cas tu appelles ton tableau array. mais ds ton prog, quel est le nom du tableau ?

Commentaire de Adeon le 01/10/2004 19:55:25

haaa ok c'est ds la variable LPVOID que retourne la fonction !
je vai essayer de mediter la dessus !

Commentaire de ymca2003 le 01/10/2004 23:23:57

dans le code, je ne fait que recopier des pixels => j'utilise un DWORD (32 bits) pour faire les mamips, d'où le cast en LPDWORD et l'absence du facteur 4


à la fin, il faut soit recréer un bitmap soit affecter les données avec SetDIBits

 Ajouter un commentaire




Nos sponsors


Appels d'offres

Sondage...

CalendriCode

Mars 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,437 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales