IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > GDI
        comment charger une image sur une fenêtre dans un projet Visual C++ ?
        Comment remplir une zone rectangle avec un dégradé de 2 ou 3 couleurs ?
        Comment extraire des Icônes dans un fichier externe ?
        Comment retrouver l'icône d'un fichier ?
        Comment obtenir la taille en pixels de l'écran ?
        Comment afficher un bitmap depuis une ressource ?
        Comment dilater/rétrécir un bitmap ?
        Comment déterminer les dimensions d'une chaîne de caractères en pixels ?
        Comment régler l'imprimante en mode paysage ?
        Comme lire une icône au format 16x16 ?
        Comment convertir un DDB (Device Dependant Bitmap) en DIB (Device Independant Bitmap) ?
        Comment écrire sur le disque un DIB (ou un Bitmap en passant au préalable par DDBToDIB) ?
        Comment obtenir un pointeur sur les Bytes d'une resource binaire ?
        Comment transformer un Buffer RGB sur 24 bits (TrueColor) en Buffer RGB 16 bits (HiColor ou HighColor) ?
        Comment attacher un bitmap à une CImageList ?
        Comment changer le contenu d'un Bitmap ?
        Comment écrire le contenu d'une fenêtre (boîte de dialogue, bouton...) dans un Bitmap ?
        Comment savoir si un CBitmap est initialisé ?
6.1. Press-Papiers (3)
                Comment copier un bitmap dans le presse-papiers ?
                Comment récupérer une image dans le presse-papiers ?
                Comment copier du texte dans le presse-papiers ?



comment charger une image sur une fenêtre dans un projet Visual C++ ?
auteur : Mat.M
( MFC ou non ,Win32,voire d'autres environnements de développements.)
C'est vrai que le gros problème de Visual C++ et classes associées ( dont MFC ) c'est de ne pas gérer les images ou "bitmaps".
Il faut tout faire par soi-même.

Basiquement pour afficher une bitmap sur une fenêtre il faut obtenir un contexte de périphérique ou HDC de la fenêtre sur laquelle on affiche la bitmap.

Le MSDN décrit largement tout cela :

Faire une copie d'écran
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_5a5h.asp

Sauvegarder des contextes graphiques ( HDC) et écrans en fichier .BMP
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_7zfp.asp3
Noter qu'il faut ajuster éventuellement la profondeur de pixels
Description des formats de fichiers images
http://www.wotsit.org

Exemples assez simples. Je préfére ceux cités ci-dessous car facilement adaptable à n'importe quel projet

http://www.cplusplus.com/src/#win32
Pour charger une BMP
http://www.cplusplus.com/src/winbmp.zip

Pour charger une image GIF http://www.cplusplus.com/src/wingif.zip

Pour charger une JPEG:
http://www.smalleranimals.com/jpegfile.htm
Fonctionne parfaitement j'ai utilisé et adopté le code source pour un projet personel.

Exemples plus évolués et complets:
http://www.codeproject.com/bitmap

http://codeguru.earthweb.com/bitmap/CPicture.html

A noter qu'il ya l'interface COM IPicture :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/htm/ctin_p_482t.asp

Librairie payante mais très compléte:
http://www.leadtools.com

Voilà à vous de jouer maintenant.


Comment remplir une zone rectangle avec un dégradé de 2 ou 3 couleurs ?
auteur : lucky

//*****************************************************************************
// rempli le rectangle donné avec un dégradé de 3 couleurs : Haut, milieu, bas
//*****************************************************************************
void RempliDegradeRectHautBas(CDC* pDC,CRect rect
,short RedHaut,short GrHaut,short BlHaut // couleur de départ du haut
,short RedMilieu,short GrMilieu,short BlMilieu // couleur du milieu
,short RedBas,short GrBas,short BlBas) // couleur du bas
{
short ColorR, ColorG, ColorB ;

int nWidth = rect.Width ();
int nHeight = rect.Height ();

// calcul de constantes intermédiaires
short ColorRinterm = RedHaut - RedMilieu ;
short ColorGinterm = GrHaut - GrMilieu ;
short ColorBinterm = BlHaut - BlMilieu ;

// remplissage d'une premiere moitiée de rectangle (haut) avec 1er dégradé
for(int i = 0; i < nHeight/2; ++i) 
{
rect.SetRect(0, i, nWidth, nHeight/2 + 1);
ColorR = RedHaut  - MulDiv(i,ColorRinterm, nHeight/2) ;
ColorG = GrHaut - MulDiv(i,ColorGinterm, nHeight/2) ;
ColorB = BlHaut - MulDiv(i,ColorBinterm, nHeight/2) ;
pDC->FillSolidRect(&rect, RGB(ColorR ,ColorG,ColorB));
}

// calcul de constantes intermédiaires
ColorRinterm = RedMilieu - RedBas;
ColorGinterm = GrMilieu - GrBas;
ColorBinterm = BlMilieu - BlBas;

// remplissage de la deuxieme moitiée de rectangle (bas) avec 2eme dégradé
for( i = nHeight/2; i < nHeight; ++i) 
{
rect.SetRect(0, i, nWidth, nHeight + 1);
ColorR = RedMilieu - MulDiv(i-nHeight/2,ColorRinterm/*70*/, nHeight/2) ;
ColorG = GrMilieu - MulDiv(i-nHeight/2,ColorGinterm/*10*/, nHeight/2) ;
ColorB = BlMilieu - MulDiv(i-nHeight/2,ColorBinterm/*10*/, nHeight/2) ;
pDC->FillSolidRect(&rect, RGB(ColorR ,ColorG,ColorB));
}

}

//********************************************************************************
// rempli le rectangle donné avec un dégradé de 3 couleurs : Gauche, milieu, Droit
//********************************************************************************
void RempliDegradeRectGaucheDroite(CDC* pDC,CRect rect
   ,short RedGauche,short GrGauche,short BlGauche // couleur de départ de gauche
   ,short RedMilieu,short GrMilieu,short BlMilieu // couleur du milieu
   ,short RedDroit,short GrDroit,short BlDroit)  // couleur de
 droite
{
short ColorR, ColorG, ColorB ;

int nWidth = rect.Width ();
int nHeight = rect.Height ();

// calcul de constantes intermédiaires
short ColorRinterm = RedGauche - RedMilieu ;
short ColorGinterm = GrGauche - GrMilieu ;
short ColorBinterm = BlGauche - BlMilieu ;

// remplissage d'une premiere moitiée de rectangle (haut) avec 1er dégradé
for(int i = 0; i < nWidth/2; ++i) 
{
rect.SetRect(i, 0, nWidth/2 + 1, nHeight);
ColorR = RedGauche  - MulDiv(i,ColorRinterm, nWidth/2) ;
ColorG = GrGauche - MulDiv(i,ColorGinterm, nWidth/2) ;
ColorB = BlGauche - MulDiv(i,ColorBinterm, nWidth/2) ;
pDC->FillSolidRect(&rect, RGB(ColorR ,ColorG,ColorB));
}

// calcul de constantes intermédiaires
ColorRinterm = RedMilieu - RedDroit;
ColorGinterm = GrMilieu - GrDroit;
ColorBinterm = BlMilieu - BlDroit;

// remplissage de la deuxieme moitiée de rectangle (bas) avec 2eme dégradé
for( i = nWidth/2; i < nWidth; ++i) 
{
rect.SetRect(i,

 0, nWidth + 1, nHeight);
ColorR = RedMilieu - MulDiv(i-nWidth/2,ColorRinterm/*70*/, nWidth/2) ;
ColorG = GrMilieu - MulDiv(i-nWidth/2,ColorGinterm/*10*/, nWidth/2) ;
ColorB = BlMilieu - MulDiv(i-nWidth/2,ColorBinterm/*10*/, nWidth/2) ;
pDC->FillSolidRect(&rect, RGB(ColorR ,ColorG,ColorB));
}

}

//*********************************************************************
// rempli le rectangle donné avec un dégradé de 2 couleurs : Haut, bas
//*********************************************************************
void RempliDegradeSimpleHautBas(CDC* pDC,CRect rect
,short RedHaut,short GrHaut,short BlHaut // couleur de départ du haut
,short RedBas,short GrBas,short BlBas) // couleur du bas

short ColorR, ColorG, ColorB ;

int nWidth = rect.Width ();
int nHeight = rect.Height ();

// remplissage du rectangle avec dégradé
for(int i = 0; i < nHeight; ++i) 
{
rect.SetRect(0, i, nWidth, nHeight + 1);
ColorR = RedHaut  - MulDiv(i,RedHaut - RedBas, nHeight) ;
ColorG = GrHaut - MulDiv(i,GrHaut - GrBas, nHeight) ;
ColorB = BlHaut - MulDiv(i,BlHaut - BlBas, nHeight) ;
pDC->FillSolidRect(&rect, RGB(ColorR ,ColorG,ColorB));
}

}

//************************************************************************
// rempli le rectangle donné avec un dégradé de 2 couleurs : Gauche, droit
//************************************************************************
void RempliDegradeSimpleGaucheDroit(CDC* pDC,CRect rect
,short RedGauche,short GrGauche,short BlGauche // couleur de départ de gauche
,short RedDroit,short GrDroit,short BlDroit)  // couleur de droite
{
short ColorR, ColorG, ColorB ;

int nWidth = rect.Width ();
int nHeight = rect.Height ();

// remplissage du rectangle avec dégradé
for(int i = 0; i < nWidth; ++i) 
{
rect.SetRect(i, 0, nWidth + 1, nHeight);
ColorR = RedGauche  - MulDiv(i,RedGauche - RedDroit, nWidth) ;
ColorG = GrGauche - MulDiv(i,GrGauche - GrDroit, nWidth) ;
ColorB = BlGauche - MulDiv(i,BlGauche - BlDroit, nWidth) ;
pDC->FillSolidRect(&rect, RGB(ColorR ,ColorG,ColorB));
}

}

Comment retrouver l'icône d'un fichier ?
auteur : Farscape
en utilisant la fonction SHGetFileInfo comme dans l'exemple ci dessous :

HICON GetIconFromFile(LPCTSTR sz)
{
    CString key,ret;
    char drive[_MAX_DRIVE];
    char dir[_MAX_DIR];
    char fname[_MAX_FNAME];
    char ext[_MAX_EXT];

    CString szpath,szext;
    HIMAGELIST hSysImageList;
    SHFILEINFO shfi;

    int nic;
    HICON hicon=NULL;

    _splitpath(sz,drive,dir,fname,ext);
    szext=ext;
    szpath=sz;
    if(!(szext.Find(".exe")!=-1 || 
            szext.Find(".pif")!=-1 ||
            szext.IsEmpty() ||
            strlen(szext)<4 ||
            szext.Find(".lnk")!=-1) &&
            SHGetFileInfo(szext,FILE_ATTRIBUTE_NORMAL,&shfi,sizeof(shfi),
            SHGFI_USEFILEATTRIBUTES|SHGFI_ICON|SHGFI_SMALLICON))
    {

        hicon=shfi.hIcon;
    }
    if(!hicon)
    {
        hSysImageList=(HIMAGELIST) SHGetFileInfo(szpath,0,&shfi,sizeof(SHFILEINFO),
                        SHGFI_SYSICONINDEX | SHGFI_SMALLICON);

        if(hSysImageList)
        {
            nic=shfi.iIcon;
            hicon=ImageList_GetIcon(hSysImageList,nic,ILD_NORMAL);
        }
    }
    return hicon;
}

Comment obtenir la taille en pixels de l'écran ?
auteur : Farscape
On obtient la taille de l'écran avec la fonction GetSystemMetrics:

int nResolx=GetSystemMetrics(SM_CXSCREEN); // resolution sur les X
int nResoly=GetSystemMetrics(SM_CYSCREEN); // resolution sur les Y

Comment afficher un bitmap depuis une ressource ?
auteur : Farscape
L'exemple ci-dessous montre les étapes nécessaires pour lire et afficher un bitmap provenant des ressources (IDB_BMPESSAI) .

CMyView::OnDraw(CDC *pDC)
{
    CBitmap Bitmap;
    CDC MemDC;
  
    Bitmap.LoadBitmap(IDB_BMPESSAI); // lecture bitmap dans les ressources
    BITMAP InfosBmp; // structure d'informations.
    Bitmap.GetBitmap(&InfosBmp);
    MemDC.CreateCompatibleDC(pDC);// creation d'un DC en memoire
    MemDC.SelectObject(&Bitmap); // selection du bitmap dans le DC en memoire
    // transfert final du bitmap dans le dc de la view.
    pDC->BitBlt( 0,0,InfosBmp.bmWidth, InfosBmp.bmHeight,
                     &MemDC,
                     0,0,
                     SRCCOPY);
}
Note: l'exemple ci-dessus fonctionne très bien à l'écran.
dans le cas d'une édition sur imprimante ce bitmap ne sera pas compatible, il faudra disposer d'un bitmap DIB: device-independent bitmap au lieu d'un DDB: device-dependent bitmap .


Comment dilater/rétrécir un bitmap ?
auteur : Farscape
Il faut utiliser la fonction StretchBlt à la place de BitBlt

CDC::StretchBlt
BOOL StretchBlt ( 
int x, 
int y, 
int nWidth, 
int nHeight, 
CDC* pSrcDC, 
int xSrc, 
int ySrc, 
int nSrcWidth, 
int nSrcHeight, 
DWORD dwRop ); 
Exemple d'affichage avec un bitmap appartenant aux ressources.

CMyView::OnDraw(CDC *pDC)
{
    CBitmap Bitmap;
    CDC MemDC;
 
    Bitmap.LoadBitmap(IDB_BMPESSAI); // lecture bitmap dans les ressources
    BITMAP InfosBmp; // structure d'informations.
    Bitmap.GetBitmap(&InfosBmp);
    MemDC.CreateCompatibleDC(pDC);// creation d'un DC en memoire
    MemDC.SelectObject(&Bitmap); // selection du bitmap dans le DC en memoire
    // transfert final du bitmap dans le dc de la view.
    // zoom x 2
    CSize Size(InfosBmp.bmWidth *2 , InfosBmp.bmHeight *2);
    pDC->DPtoLP(&Size);// si le systeme de coordonnées n'est pas MM_TEXT
    pDC->StretchBlt( 0, 0,
                     Size.cx,-Size.cy,
                     &MemDC,
                     0, 0,
                     InfosBmp.bmWidth, InfosBmp.bmHeight,
                     SRCCOPY); 
} 
Note: Pour la réduction d'un bitmap il est conseillé d'appliquer un :

    pDC->SetStretchBltMode( COLORONCOLOR );
Avant le StretchBlt,COLORONCOLOR donne un meilleur aspect aux bitmaps rétrécis.


Comment déterminer les dimensions d'une chaîne de caractères en pixels ?
auteur : Farscape
En utilisant la fonction :

CDC::GetTextExtent
CSize GetTextExtent( LPCTSTR lpszString, int nCount ) const;
CSize GetTextExtent( const CString& str ) const;
Exemple d'utilisation :

CClientDC dc(this);
CFont* pFont = dc.SelectObject(m_pMyFont); // sélection d'une fonte .
CSize size=dc.GetTextExtent(string);
La variable size contiendra la hauteur (size.cy) et largeur (size.cx) de la chaîne pour la fonte en cours.
Après il est facile de calculer un rectangle d'occupation à partir d'une position x,y.


Comment régler l'imprimante en mode paysage ?
auteur : Farscape
Pour spécifier le mode d'impression portrait ou paysage sur une imprimante il faut disposer d'un pointeur sur la structure DEVMODE qui contient les données liées à l'imprimante.
Le code ci-dessous commence par récupérer l'imprimante par défaut pour utiliser le pointeur m_hDevMode qui est une donnée membre de la classe CWinApp.

void CMyApp::SetLandscapeMode() 
{ 
   PRINTDLG pd; 
   pd.lStructSize=(DWORD)sizeof(PRINTDLG); 
   BOOL bRet=GetPrinterDeviceDefaults(&pd); 
   if(bRet) 
   { 
      // protect memory handle with ::GlobalLock and ::GlobalUnlock 
      DEVMODE FAR *pDevMode=(DEVMODE FAR *)::GlobalLock(m_hDevMode); 
      // set orientation to landscape 
      pDevMode->dmOrientation=DMORIENT_LANDSCAPE; 
      ::GlobalUnlock(m_hDevMode); 
   } 
}

Comme lire une icône au format 16x16 ?
Mise à jour le 17/09/2007[haut]
auteur : Farscape
Dans Visual Studio on peut définir pour le même identifiant de ressource une icône au format 32x32 et 16x16 pixels.
la fonction

HICON CWinApp::LoadIcon( UINT nIDResource ) const; 
Lit par défaut l'icône au format 32x32 .
pour la lecture du format 16x16 on procédera comme suit:

HICON hIcon = (HICON)::LoadImage(   AfxFindResourceHandle(MAKEINTRESOURCE(IDI_MYICONE),RT_GROUP_ICON),
                                    MAKEINTRESOURCE(IDI_MYICONE),
                                    IMAGE_ICON,
                                    16,16,LR_DEFAULTSIZE);
/*CStatic */m_MyStatic.SetIcon( hIcon ); 
IDI_MYICONE représente l'identifiant de l'icône à lire.
Note: l'icône devra étre libérée par un DestroyIcon

HICON hIcon =m_MyStatic.GetIcon();
if(hIcon) ::DestroyIcon(hIcon);

Comment convertir un DDB (Device Dependant Bitmap) en DIB (Device Independant Bitmap) ?
Créé le 27/11/2005[haut]
auteur : matazz

/*******************************************************************************/
// DDBToDIB- Creates a DIB from a DDB
// bitmap- Device dependent bitmap
// dwCompression- Type of compression - see BITMAPINFOHEADER
// pPal- Logical palette
/*******************************************************************************/
HANDLE DDBToDIB( CBitmap& bitmap, DWORD dwCompression, CPalette* pPal )
{
    BITMAPbm;
    BITMAPINFOHEADERbi;
    LPBITMAPINFOHEADER lpbi;
    DWORDdwLen;
    HANDLEhDIB;
    HANDLEhandle;
    HDC hDC;
    HPALETTEhPal;
    
    
    ASSERT( bitmap.GetSafeHandle() );
    
    // The function has no arg for bitfields
    if( dwCompression == BI_BITFIELDS )
        return NULL;
    
    // If a palette has not been supplied use defaul palette
    hPal = (HPALETTE) pPal->GetSafeHandle();
    if (hPal==NULL)
        hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
    
    // Get bitmap information
    bitmap.GetObject(sizeof(bm),(LPSTR)&bm);
    
    // Initialize the bitmapinfoheader
    bi.biSize= sizeof(BITMAPINFOHEADER);
    bi.biWidth= bm.bmWidth;
    bi.biHeight = bm.bmHeight;
    bi.biPlanes = 1;
    bi.biBitCount= bm.bmPlanes * bm.bmBitsPixel;
    bi.biCompression= dwCompression;
    bi.biSizeImage= 0;
    bi.biXPelsPerMeter= 0;
    bi.biYPelsPerMeter= 0;
    bi.biClrUsed= 0;
    bi.biClrImportant= 0;
    
    // Compute the size of the  infoheader and the color table
    int nColors = (1 << bi.biBitCount);
    if( nColors > 256 )
        nColors = 0;
    dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);
    
    // We need a device context to get the DIB from
    hDC = GetDC(NULL);
    hPal = SelectPalette(hDC,hPal,FALSE);
    RealizePalette(hDC);
    
    // Allocate enough memory to hold bitmapinfoheader and color table
    hDIB = GlobalAlloc(GMEM_FIXED,dwLen);
    
    if (!hDIB)
    {
        SelectPalette(hDC,hPal,FALSE);
        ReleaseDC(NULL,hDC);
        return NULL;
    }
    
    lpbi = (LPBITMAPINFOHEADER)hDIB;
    
    *lpbi = bi;
    
    // Call GetDIBits with a NULL lpBits param, so the device driver 
    // will calculate the biSizeImage field 
    GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
        (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
    
    bi = *lpbi;
    
    // If the driver did not fill in the biSizeImage field, then compute it
    // Each scan line of the image is aligned on a DWORD (32bit) boundary
    if (bi.biSizeImage == 0){
        bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
            * bi.biHeight;
        
        // If a compression scheme is used the result may infact be larger
        // Increase the size to account for this.
        if (dwCompression != BI_RGB)
            bi.biSizeImage = (bi.biSizeImage * 3) / 2;
    }
    
    // Realloc the buffer so that it can hold all the bits
    dwLen += bi.biSizeImage;
    if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
        hDIB = handle;
    else{
        GlobalFree(hDIB);
        
        // Reselect the original palette
        SelectPalette(hDC,hPal,FALSE);
        ReleaseDC(NULL,hDC);
        return NULL;
    }
    
    // Get the bitmap bits
    lpbi = (LPBITMAPINFOHEADER)hDIB;
    
    // FINALLY get the DIB
    BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
        0L,// Start scan line
        (DWORD)bi.biHeight,// # of scan lines
        (LPBYTE)lpbi // address for bitmap bits
        + (bi.biSize + nColors * sizeof(RGBQUAD)),
        (LPBITMAPINFO)lpbi,// address of bitmapinfo
        (DWORD)DIB_RGB_COLORS);// Use RGB for color table
    
    if( !bGotBits )
    {
        GlobalFree(hDIB);
        
        SelectPalette(hDC,hPal,FALSE);
        ReleaseDC(NULL,hDC);
        return NULL;
    }   
    SelectPalette(hDC,hPal,FALSE);
    ReleaseDC(NULL,hDC);
    return hDIB;
}

Comment écrire sur le disque un DIB (ou un Bitmap en passant au préalable par DDBToDIB) ?
Créé le 27/11/2005[haut]
auteur : matazz

/*******************************************************************************/
//LPTSTR szFile : DestFile
//HANDLE hDIB  : Handle sur un DIB (convertis depuis un CBitmap par DDBToDIB)
/*******************************************************************************/
BOOL WriteDIB( LPTSTR szFile, HANDLE hDIB)
{
BITMAPFILEHEADERhdr;
LPBITMAPINFOHEADERlpbi;

if (!hDIB)
return FALSE;

CFile file;
if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) )
return FALSE;

lpbi = (LPBITMAPINFOHEADER)hDIB;

int nColors = 1 << lpbi->biBitCount;

// Fill in the fields of the file header 
hdr.bfType= ((WORD) ('M' << 8) | 'B');// is always "BM"
hdr.bfSize= GlobalSize (hDIB) + sizeof( hdr );
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits= (DWORD) (sizeof( hdr ) + lpbi->biSize +
nColors * sizeof(RGBQUAD));

// Write the file header 
file.Write( &hdr, sizeof(hdr) );

// Write the DIB header and the bits 
file.Write( lpbi, GlobalSize(hDIB) );

file.Close();

return TRUE;
}

Comment obtenir un pointeur sur les Bytes d'une resource binaire ?
Créé le 27/11/2005[haut]
auteur : matazz

HINSTANCEhIn= NULL;
HRSRCSrc= NULL;
HGLOBAL hMem= NULL;
DWORD rsize= NULL;
CStringRSNumb;

RSNumb.Format("#%d",IDR_RESOURCE_BINAIRE);

hIn= ::AfxGetResourceHandle();
//ou BINARY est un Dossier dans l'onglet resource (Comme Dilalog)
//à l'import d'une resource binaire, il demande le resource Type
//c'est en fait le nom qu'il va donner au dossier
tSrc= ::FindResource(hIn,RSNumb.GetBuffer(0),"BINARY");
rsize= ::SizeofResource(hModule,hRes);
hMem= ::LoadResource(hModule,hRes);
if (hMem)
{
    BYTE *pData = (BYTE *) ::LockResource(hMem);
    if (pData)
    {
        //travaille avec la resource
    }
}
else 
{
    AfxmessageBox("Unable to load resource!");
}

Comment transformer un Buffer RGB sur 24 bits (TrueColor) en Buffer RGB 16 bits (HiColor ou HighColor) ?
Mise à jour le 29/01/2006[haut]
auteur : matazz
Une couleur RGB en 24bits est codée sur 3 octets (1 par composante soit 8 bits).
Une couleur RGB en 16bits est codée sur 2 octets (soit 5 bits par composantes voire 6 pour le Vert (couleur plus visible par l'oeil humain)).

Tout d'abord voici deux liens concernant le codage des images RGB sur 15 et 16 bits :
http://en.wikipedia.org/wiki/Color_depth
http://en.wikipedia.org/wiki/HiColor

Définitions :
-RGB555 : Codage d'une couleur d'un pixel sur 15 bits (5 pour le R, 5 pour le G et 5 pour le B).
Le tout tiens sur 2 octets, 1 bit étant inutilisé.
-RGB565 : Codage d'une couleur d'un pixel sur 16 bits (5 pour le R, 6 pour le G et 5 pour le B).
Le tout tiens sur 2 octets.

En fait il faut distinguer RGB555 (15 bits) et RGB565 (16 bits).
En théorie il est possible de toujours coder en RGB565 puisque si le décodeur ne gère que le RGB555 par le jeu des masques, vous perdez l'information supplémentaire sur la composante Verte, mais la couleur restera proche de celle que vous avez codé.

Le principe de ce codage, utilisé dans le format BMP et d'enlever les 3 bits de poids Faible de chaque composante (R,G et B) afin d'économiser un octet par pixel.
Ceci permet de créer des paliers de valeurs :
Par exemple si une des composantes vaut 0xFF (1111 1111) , 0xFE (1111 1110), 0xFD(1111 1101)....jusqu'a 0xF8 (1111 1000) toutes ces valeurs auront pour équivalant en codage 15 bits 0x1F (1111 1) soit 0xF8 (1111 1000) dont les 3 bits de poids faible ont été enlevés par décalage à droite.

Donc en fait il suffit de travailler avec des WORD pour chaque composante (R,G et B) et d'assembler le tout par décalage.
Donc en gros par un masque 0xF8 (1111 1000) et un ET logique les 3 bits de poids faible sont enlevés, ensuite il faut faire un décalage à droite de 3 bits.
Mais comme il faut redécaler à gauche pour assembler les composantes (10 pour le R(11 en 16 bits), 5 pour le G, et 0 pour le B) les valeurs du décalage sont 3 à droite pour le Bleu, 2 (3-5) à gauche pour le G et 7(3-7) à gauche pour le R.
Enfin il faut faire un swap du byte de poids fort avec celui de poids faible (en tout cas sous windows et en mémoire, je n'ai pas essayé d'écrire un fichier) en fonction de mode d'écriture LittleEndian ou BigEndian...


   WORD   B,G,R;
     //Application du masque pour retirer les 3 bits de poids faible
     //Dans le cas du 16 bits le masque pour le vert est 0xFC
   B = BuffBGR[Ind  ] & 0xF8;
   G = BuffBGR[Ind+1] & 0xF8;
   R = BuffBGR[Ind+2] & 0xF8;

    //application des décalages
   B = (B>>3);
   G = (G<<2);
   R = (R<<7);

    //composition des valeurs
   WORD BGR16Bit = (R + G + B);
     
    //Et swap entre le byte de poid fort et de poid faible.
   BGR16Bit = (BGR16Bit << 8) + (BGR16Bit >> 8); 
Exemple : Prenons une couleur verte (94, 228, 94)
Prenons sa valeur hexa et binaire sur 24 bits :

5E (01011110) E4(11100100) 5E(01011110)
En appliquant le masque 0xF8 (11111000) à chaque composante on obtient 58 (01011000) E0 (11100000) 58 (01011000) soit la couleur (88, 224, 88 ).

Vous pouvez faire le test dans Photoshop et la différence à l'oeil est minime.

Ensuite il suffit d'enlever les 3 bits de poids faible (en gras)et d' assembler le reste sur 2 octets.


Comment attacher un bitmap à une CImageList ?
Créé le 27/11/2005[haut]
auteur : Farscape
l'exemple ci-dessous attache directement une ressouce Bitmap (IDB_BITMAP1) à l'objet ImageList.

CImageList ImageList;// attention l'objet ne doit pas etre locale a une fonction
ImageList.Attach(ImageList_LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1), 35, 1, RGB(255, 0, 255)));

Comment changer le contenu d'un Bitmap ?
Créé le 20/05/2006[haut]
auteur : Farscape
Depuis Visual.Net nous disposons de la classe CImage permettant des manipulations sur les bitmaps, notamment la fonction SetPixel.
Exemple:

CBitmap Bmp; 
CImage Image; 
int         i; 

Bmp.LoadBitmap(IDB_MON_IMAGE); // image 100x16 en couleur vraie Windows 
Image.Attach(Bmp, Image.DIBOR_DEFAULT); 

for(int i=0; i<16;i++) 
{ 
  Image.SetPixel(99,i,RGB(0,0,0)); 
}

Comment écrire le contenu d'une fenêtre (boîte de dialogue, bouton...) dans un Bitmap ?
Créé le 20/05/2006[haut]
auteur : matazz
En utilisant les 2 fonctions précédentes :

/*******************************************************************************/
// par Zafir Anjum  http://www.codeguru.com/Cpp/G-M/bitmap/article.php/c1741
// WriteWindowToDIB par Zafir Anjum 
// LPTSTR DestFile
// Pointeur sur un CWnd
/*******************************************************************************/
BOOL WriteWindowToDIB( LPTSTR szFile, CWnd *pWnd )
{
    CBitmap bitmap;
    CWindowDCdc(pWnd);
    CDC memDC;
    CRectrect;
    
    memDC.CreateCompatibleDC(&dc);
    pWnd->GetWindowRect(rect);
    
    bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height() );
    
    CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
    memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY);
    
    // Create logical palette if device support a palette
    CPalette pal;
    if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
    {
        UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
        LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
        pLP->palVersion = 0x300;
        
        pLP->palNumEntries =
            GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry );
        
        // Create the palette
        pal.CreatePalette( pLP );
        
        delete[] pLP;
    }
    memDC.SelectObject(pOldBitmap);
    
    // Convert the bitmap to a DIB
    HANDLE hDIB = DDBToDIB( bitmap, BI_RGB, &pal );    
    if( hDIB == NULL )return FALSE;

    // Write it to file
    WriteDIB( szFile, hDIB );   
    // Free the memory allocated by DDBToDIB for the DIB
    GlobalFree( hDIB );
    return TRUE;
}

Comment savoir si un CBitmap est initialisé ?
Créé le 22/01/2007[haut]
auteur : Farscape
pour savoir si un CBitmap est déjà initialisé, on testera la valeur du handle GDI attaché, ici un HBITMAP.

if(!static_cast<HBITMAP>(m_bitmap))
     m_bitmap.CreateCompatibleBitmap( dc, rcClient.Width(), rcClient.Height() );




Consultez les autres F.A.Q.


Valid XHTML 1.0 TransitionalValid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2004 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.