begin process at 2008 07 06 13:04:24
1 205 544 membres
121 nouveaux aujourd'hui
14 119 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

RECOPIE ZONE BITMAP AVEC REDIMENSIONNEMENT POSSIBLE (STRETCHBLT WIN32)


Information sur la source

Catégorie :Graphique Niveau : Débutant Date de création : 09/06/2004 Vu / téléchargé: 5 895 / 573

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

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (8)
Ajouter un commentaire et/ou une note

Description

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);
}
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

  • signaler à un administrateur
    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...

  • signaler à un administrateur
    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.


  • signaler à un administrateur
    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.

  • signaler à un administrateur
    Commentaire de ymca2003 le 10/06/2004 12:19:40

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

  • signaler à un administrateur
    Commentaire de coucou720 le 27/07/2005 19:11:09

    Bonjour j utilise ton code et je n ai pas de problemes quand je charge le bitmap a partir d un fichier via LoadBitmap(...).
    Seulement je veux faire cela a partir de quelquechose qui affiche dans un HDC. je récupere donc le HBITMAP attaché a ce HDC... j ai un beau bitmap que je peux afficher dans mon HDC, ok c est cool ... mais quand j utilise ta fonction RedimBmp(...)  ca ne marche absolument pas ...
    (mon bitmap est crée avec CreateCompatibleBitmap(hdc , ....)
    Si tu peux m aider ca serai super bien :)

  • signaler à un administrateur
    Commentaire de acrcorp le 22/04/2006 22:26:34

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

  • signaler à un administrateur
    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.

  • signaler à un administrateur
    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

Pub



Appels d'offres

Plugin Dialer outlook
Budget : 2 000€
Travail graphique- ill...
Budget : 1 000€
creation de marque et ...
Budget : 1 000€

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Boutique

Boutique de goodies CodeS-SourceS