begin process at 2012 02 10 11:25:39
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Graphique

 > RECOPIE ZONE BITMAP AVEC REDIMENSIONNEMENT POSSIBLE (STRETCHBLT WIN32)

RECOPIE ZONE BITMAP AVEC REDIMENSIONNEMENT POSSIBLE (STRETCHBLT WIN32)


 Information sur la source

Note :
7,67 / 10 - par 3 personnes
7,67 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Graphique Niveau :Débutant Date de création :09/06/2004 Vu / téléchargé :8 468 / 664

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
Quelques fonctions permettant de créer un bitmap qui soit la copie d'une zone d'un autre bitmap avec un redimensionnement possible. En gros montre comment utiliser StretchBlt pour créer un nouveau bitmap.

Source

  • //*****************************************************************************
  • // DimBmp.cpp :
  • //
  • //*****************************************************************************
  • #include <windows.h>
  • #include "Resource.h"
  • //=============================================================================
  • // Variables globales.
  • //=============================================================================
  • HINSTANCE g_hAppInstance = NULL; // instance de l'application
  • HWND g_hWndMainFrame = NULL; // fenêtre principale
  • HBITMAP g_hBmpSrc = NULL; // bitmap source
  • HBITMAP g_hBmpDst = NULL; // bitmap destination
  • //=============================================================================
  • // Fonctions du module.
  • //=============================================================================
  • BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);
  • SIZE GetBmpSize (HBITMAP hBmp);
  • HBITMAP RedimBmp (HDC hdc, HBITMAP hBmpScr, RECT rcSrc, SIZE sizeDst);
  • void DrawBmp (HDC hdc, int x, int y, HBITMAP hBmp);
  • LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  • //*****************************************************************************
  • // WinMain : point d'entrée du programme.
  • //*****************************************************************************
  • int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  • LPSTR lpCmdLine, int nCmdShow)
  • {
  • // initialisation de l'application
  • if(!InitInstance(hInstance, nCmdShow))
  • return 0;
  • // boucle de messages
  • MSG msg;
  • while(GetMessage(&msg, NULL, 0, 0))
  • {
  • TranslateMessage(&msg);
  • DispatchMessage(&msg);
  • }
  • return msg.wParam;
  • }
  • //*****************************************************************************
  • // InitInstance : initialisation de l'application, création de la fenêtre
  • // principale.
  • //*****************************************************************************
  • BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  • {
  • // sauvegarde de l'instance de l'application
  • g_hAppInstance = hInstance;
  • char szWndClass[] = "DimBmpWnd";
  • char szWndTitle[] = "DimBmp";
  • // classe de fenêtre
  • WNDCLASS wc;
  • ZeroMemory(&wc, sizeof(WNDCLASS));
  • wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  • wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  • wc.hInstance = g_hAppInstance;
  • wc.lpfnWndProc = WndProc;
  • wc.style = CS_HREDRAW|CS_VREDRAW;
  • wc.lpszClassName = szWndClass;
  • wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  • if(!RegisterClass(&wc))
  • return FALSE;
  • // création de la fenêtre
  • g_hWndMainFrame = CreateWindow(szWndClass, szWndTitle, WS_OVERLAPPEDWINDOW,
  • CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
  • NULL, NULL, g_hAppInstance, NULL);
  • if(g_hWndMainFrame == NULL)
  • return FALSE;
  • // affichage
  • ShowWindow(g_hWndMainFrame, nCmdShow);
  • UpdateWindow(g_hWndMainFrame);
  • return TRUE;
  • }
  • //*****************************************************************************
  • // 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;
  • }
  • //*****************************************************************************
  • // RedimBmp : crée un bitmap en recopiant une zone d'un autre bitmap avec un
  • // redimensionnement éventuel.
  • // entrée : hdc : DC à utiliser pour créer les DCs compatibles (DC de la
  • // fenêtre principale ou de l'écran par exemple).
  • // hBmpSrc : bitmap source.
  • // rcSrc : zone du bitmap source à recopier ou {0,0,0,0} pour
  • // recopier l'intégralité.
  • // sizeDst : taille du bitmap de destination ou {0,0} pour calculer
  • // la taille à partir de rcSrc (pas de redimensionnement).
  • // retour : bitmap créé.
  • //*****************************************************************************
  • HBITMAP RedimBmp(HDC hdc, HBITMAP hBmpSrc, RECT rcSrc, SIZE sizeDst)
  • {
  • // taille du bitmap initial
  • SIZE sizeSrc = GetBmpSize(hBmpSrc);
  • // si rcSrc est à {0,0,0,0}, on prend toute l'image source
  • if(rcSrc.left==0 && rcSrc.top==0 && rcSrc.right==0 && rcSrc.bottom==0)
  • {
  • rcSrc.right = sizeSrc.cx;
  • rcSrc.bottom = sizeSrc.cy;
  • }
  • // vérification des bornes
  • if(rcSrc.left < 0)
  • rcSrc.left = 0;
  • if(rcSrc.top < 0)
  • rcSrc.top = 0;
  • if(rcSrc.right > sizeSrc.cx)
  • rcSrc.right = sizeSrc.cx;
  • if(rcSrc.bottom > sizeSrc.cy)
  • rcSrc.bottom = sizeSrc.cy;
  • // si sizeDst est à {0,0}, on ne fait pas de redimensionnement
  • if(sizeDst.cx==0 && sizeDst.cy==0)
  • {
  • sizeDst.cx = rcSrc.right-rcSrc.left;
  • sizeDst.cy = rcSrc.bottom-rcSrc.top;
  • }
  • //création de DCs compatibles et du bitmap de destination
  • HDC hDCSrc = CreateCompatibleDC(hdc);
  • HDC hDCDst = CreateCompatibleDC(hdc);
  • HBITMAP hBmpDst = CreateCompatibleBitmap(hdc, sizeDst.cx, sizeDst.cy);
  • // sélection des bitmaps dans les DCs (avec sauvegarde des anciens)
  • HBITMAP hOldBmpSrc = (HBITMAP)SelectObject(hDCSrc, hBmpSrc);
  • HBITMAP hOldBmpDst = (HBITMAP)SelectObject(hDCDst, hBmpDst);
  • // recopie
  • SetStretchBltMode(hDCDst, HALFTONE);
  • StretchBlt(hDCDst, 0, 0, sizeDst.cx, sizeDst.cy, hDCSrc,
  • rcSrc.left, rcSrc.top,
  • rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top, SRCCOPY);
  • // sélection des anciens bitmaps dans les DCS
  • SelectObject(hDCSrc, hOldBmpSrc);
  • SelectObject(hDCDst, hOldBmpDst);
  • // destruction des DCs
  • DeleteDC(hDCSrc);
  • DeleteDC(hDCDst);
  • // retour
  • return hBmpDst;
  • }
  • //*****************************************************************************
  • // DrawBmp : dessine un bitmap dans un DC.
  • // entrée : hdc : DC où dessiner le bitmap.
  • // x : coordonnée en x où dessiner le bitmap.
  • // y : coordonnée en y où dessiner le bitmap.
  • // hBmp : bitmap à dessiner.
  • //*****************************************************************************
  • void DrawBmp(HDC hdc, int x, int y, HBITMAP hBmp)
  • {
  • // création d'un DC compatible pour y sélectionner le bitmap à dessiner
  • HDC hDCBmp = CreateCompatibleDC(hdc);
  • HBITMAP hOldBmp = (HBITMAP)SelectObject(hDCBmp, hBmp);
  • // recopie
  • SIZE sizeBmp = GetBmpSize(hBmp);
  • BitBlt(hdc, x, y, sizeBmp.cx, sizeBmp.cy, hDCBmp, 0, 0, SRCCOPY);
  • // sélection ancien bitmap et destruction du DC
  • SelectObject(hDCBmp, hOldBmp);
  • DeleteDC(hDCBmp);
  • }
  • //*****************************************************************************
  • // WndProc : procédure de traitement des messages de la fenêtre principale.
  • //*****************************************************************************
  • LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  • {
  • // en fonction du message
  • switch(uMsg)
  • {
  • case WM_CREATE :
  • {
  • // chargement du bitmap, récupération d'une zone avec
  • // redimensionnement
  • g_hBmpSrc = LoadBitmap(g_hAppInstance, MAKEINTRESOURCE(IDB_SPRITE));
  • RECT rcSrc = {30, 0, 70, 40};
  • SIZE sizeDst = {80, 80};
  • HDC hdc = GetDC(hWnd);
  • g_hBmpDst = RedimBmp(hdc, g_hBmpSrc, rcSrc, sizeDst);
  • ReleaseDC(hWnd, hdc);
  • return 0;
  • }
  • case WM_DESTROY :
  • {
  • // destruction des bitmaps, fin de l'application
  • DeleteObject(g_hBmpSrc);
  • DeleteObject(g_hBmpDst);
  • PostQuitMessage(0);
  • return 0;
  • }
  • case WM_PAINT :
  • {
  • // début du dessin
  • PAINTSTRUCT ps;
  • HDC hdc = BeginPaint(hWnd, &ps);
  • // dessin des bitmaps
  • DrawBmp(hdc, 0, 0, g_hBmpSrc);
  • DrawBmp(hdc, 200, 0, g_hBmpDst);
  • // fin du dessin
  • EndPaint(hWnd, &ps);
  • return 0;
  • }
  • }
  • // traitement par défaut
  • return DefWindowProc(hWnd, uMsg, wParam, lParam);
  • }
//*****************************************************************************
// DimBmp.cpp :
//
//*****************************************************************************

#include <windows.h>

#include "Resource.h"

//=============================================================================
// Variables globales.
//=============================================================================
HINSTANCE	g_hAppInstance	= NULL;	// instance de l'application
HWND		g_hWndMainFrame	= NULL;	// fenêtre principale

HBITMAP		g_hBmpSrc		= NULL;	// bitmap source
HBITMAP		g_hBmpDst		= NULL;	// bitmap destination

//=============================================================================
// Fonctions du module.
//=============================================================================
BOOL	InitInstance(HINSTANCE hInstance, int nCmdShow);
SIZE	GetBmpSize	(HBITMAP hBmp);
HBITMAP	RedimBmp	(HDC hdc, HBITMAP hBmpScr, RECT rcSrc, SIZE sizeDst);
void	DrawBmp		(HDC hdc, int x, int y, HBITMAP hBmp);

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

//*****************************************************************************
// WinMain : point d'entrée du programme.
//*****************************************************************************
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine, int nCmdShow)
{
	// initialisation de l'application
	if(!InitInstance(hInstance, nCmdShow))
		return 0;

	// boucle de messages
	MSG msg;
	while(GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}

//*****************************************************************************
// InitInstance : initialisation de l'application, création de la fenêtre
//                principale.
//*****************************************************************************
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	// sauvegarde de l'instance de l'application
	g_hAppInstance = hInstance;
	char szWndClass[] = "DimBmpWnd";
	char szWndTitle[] = "DimBmp";

	// classe de fenêtre
	WNDCLASS wc;
	ZeroMemory(&wc, sizeof(WNDCLASS));
	wc.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);
	wc.hInstance		= g_hAppInstance;
	wc.lpfnWndProc		= WndProc;
	wc.style			= CS_HREDRAW|CS_VREDRAW;
	wc.lpszClassName	= szWndClass;
	wc.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	if(!RegisterClass(&wc))
		return FALSE;

	// création de la fenêtre
	g_hWndMainFrame = CreateWindow(szWndClass, szWndTitle, WS_OVERLAPPEDWINDOW,
				CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
				NULL, NULL, g_hAppInstance, NULL);
	if(g_hWndMainFrame == NULL)
		return FALSE;

	// affichage
	ShowWindow(g_hWndMainFrame, nCmdShow);
	UpdateWindow(g_hWndMainFrame);
	return TRUE;
}

//*****************************************************************************
// 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;
}

//*****************************************************************************
// RedimBmp : crée un bitmap en recopiant une zone d'un autre bitmap avec un
//            redimensionnement éventuel.
// entrée : hdc     : DC à utiliser pour créer les DCs compatibles (DC de la
//                    fenêtre principale ou de l'écran par exemple).
//          hBmpSrc : bitmap source.
//          rcSrc   : zone du bitmap source à recopier ou {0,0,0,0} pour
//                    recopier l'intégralité.
//          sizeDst : taille du bitmap de destination ou {0,0} pour calculer
//                    la taille à partir de rcSrc (pas de redimensionnement).
// retour : bitmap créé.
//*****************************************************************************
HBITMAP RedimBmp(HDC hdc, HBITMAP hBmpSrc, RECT rcSrc, SIZE sizeDst)
{
	// taille du bitmap initial
	SIZE sizeSrc = GetBmpSize(hBmpSrc);

	// si rcSrc est à {0,0,0,0}, on prend toute l'image source
	if(rcSrc.left==0 && rcSrc.top==0 && rcSrc.right==0 && rcSrc.bottom==0)
	{
		rcSrc.right		= sizeSrc.cx;
		rcSrc.bottom	= sizeSrc.cy;
	}
	// vérification des bornes
	if(rcSrc.left < 0)
		rcSrc.left = 0;
	if(rcSrc.top < 0)
		rcSrc.top = 0;
	if(rcSrc.right > sizeSrc.cx)
		rcSrc.right = sizeSrc.cx;
	if(rcSrc.bottom > sizeSrc.cy)
		rcSrc.bottom = sizeSrc.cy;

	// si sizeDst est à {0,0}, on ne fait pas de redimensionnement
	if(sizeDst.cx==0 && sizeDst.cy==0)
	{
		sizeDst.cx = rcSrc.right-rcSrc.left;
		sizeDst.cy = rcSrc.bottom-rcSrc.top;
	}

	//création de DCs compatibles et du bitmap de destination
	HDC hDCSrc = CreateCompatibleDC(hdc);
	HDC hDCDst = CreateCompatibleDC(hdc);
	HBITMAP hBmpDst = CreateCompatibleBitmap(hdc, sizeDst.cx, sizeDst.cy);

	// sélection des bitmaps dans les DCs (avec sauvegarde des anciens)
	HBITMAP hOldBmpSrc = (HBITMAP)SelectObject(hDCSrc, hBmpSrc);
	HBITMAP hOldBmpDst = (HBITMAP)SelectObject(hDCDst, hBmpDst);

	// recopie
	SetStretchBltMode(hDCDst, HALFTONE);
	StretchBlt(hDCDst, 0, 0, sizeDst.cx, sizeDst.cy, hDCSrc,
			rcSrc.left, rcSrc.top, 
			rcSrc.right-rcSrc.left, rcSrc.bottom-rcSrc.top, SRCCOPY);

	// sélection des anciens bitmaps dans les DCS
	SelectObject(hDCSrc, hOldBmpSrc);
	SelectObject(hDCDst, hOldBmpDst);

	// destruction des DCs
	DeleteDC(hDCSrc);
	DeleteDC(hDCDst);

	// retour
	return hBmpDst;
}

//*****************************************************************************
// DrawBmp : dessine un bitmap dans un DC.
// entrée : hdc : DC où dessiner le bitmap.
//          x    : coordonnée en x où dessiner le bitmap.
//          y    : coordonnée en y où dessiner le bitmap.
//          hBmp : bitmap à dessiner.
//*****************************************************************************
void DrawBmp(HDC hdc, int x, int y, HBITMAP hBmp)
{
	// création d'un DC compatible pour y sélectionner le bitmap à dessiner
	HDC hDCBmp = CreateCompatibleDC(hdc);
	HBITMAP hOldBmp = (HBITMAP)SelectObject(hDCBmp, hBmp);

	// recopie
	SIZE sizeBmp = GetBmpSize(hBmp);
	BitBlt(hdc, x, y, sizeBmp.cx, sizeBmp.cy, hDCBmp, 0, 0, SRCCOPY);

	// sélection ancien bitmap et destruction du DC
	SelectObject(hDCBmp, hOldBmp);
	DeleteDC(hDCBmp);
}

//*****************************************************************************
// WndProc : procédure de traitement des messages de la fenêtre principale.
//*****************************************************************************
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	// en fonction du message
	switch(uMsg)
	{
	case WM_CREATE :
		{
			// chargement du bitmap, récupération d'une zone avec
			// redimensionnement
			g_hBmpSrc = LoadBitmap(g_hAppInstance, MAKEINTRESOURCE(IDB_SPRITE));
			RECT rcSrc = {30, 0, 70, 40};
			SIZE sizeDst = {80, 80};
			HDC hdc = GetDC(hWnd);
			g_hBmpDst = RedimBmp(hdc, g_hBmpSrc, rcSrc, sizeDst);
			ReleaseDC(hWnd, hdc);
			return 0;
		}
	case WM_DESTROY :
		{
			// destruction des bitmaps, fin de l'application
			DeleteObject(g_hBmpSrc);
			DeleteObject(g_hBmpDst);
			PostQuitMessage(0);
			return 0;
		}
	case WM_PAINT :
		{
			// début du dessin
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hWnd, &ps);

			// dessin des bitmaps
			DrawBmp(hdc, 0, 0, g_hBmpSrc);
			DrawBmp(hdc, 200, 0, g_hBmpDst);

			// fin du dessin
			EndPaint(hWnd, &ps);
			return 0;
		}
	}

	// traitement par défaut
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}


 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 APPLICATION DE DESSIN DE QUELQUES FIGURES par laguchori
Source avec Zip Source avec une capture HDR EXPOSURE FUSION par mecrosoft
Source avec Zip Source avec une capture IRC CLIENT MULTISERVEUR EN MFC (TXIRC) par TeniX
Source avec Zip ENTETE DU FICHIER BMP (BIPMAP) par k.Lutchi
Source avec Zip Source avec une capture XCOUPE : COUPE 2D par pop70

Commentaires et avis

Commentaire de BruNews le 09/06/2004 13:30:11 administrateur CS

Salut,

regarde si ta func RedimBmp() ne PUSH pas 8 fois, me semble que devrait.
Si oui, c'est beaucoup et ne conviendrait-il pas de lui passer juste 1 pointeur de struct contenant les params a la maniere de CreateFontIndirect ? 7 PUSH de moins c'est non negligeable en terme de perf.

ciao...

Commentaire de ymca2003 le 09/06/2004 16:32:49

j'y pensais (déja passer RECT et SIZE en pointeur ou référence) mais bon j'ai fait ça assez vite fait car ça fait pas mal de fois que qq'1 pose la question sur les redimensionement avec StretchBlt.


Commentaire de BruNews le 09/06/2004 16:46:28 administrateur CS

Rassure toi, 10 contre 1 que tu vois la meme question des la semaine prochaine.

Commentaire de ymca2003 le 10/06/2004 12:19:40

pari gagné la question vient d'etre posée...

Commentaire de acrcorp le 22/04/2006 22:26:34

Quand on trouve ce qu'on cherche, on dit merci !
Alors merci ;)

Commentaire de jayjay13 le 23/03/2007 16:20:08

Salut, ces fonctions marchent très bien c'est cool elles sont faciles à comprendre.
Mais dans mon projet j'utilise des CBitmap.

Question : est-il possible de convertir un CBitmap en HBitmap ?
           ou modifier la fonction RedimBmp() pour qu'elle prenne un CBitmap en entrée ??

Merci de votre aide.

Commentaire de ymca2003 le 27/03/2007 14:32:31

Il y a une conversion automatique de CBitmap vers HBITMAP.
Il est également possible d'associer un HBITMAP à un CBitmap avec CBitmap::Attach

 Ajouter un commentaire




Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

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 : 4,586 sec (3)

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