2010-12-15 109 views
1

Une fois que je l'ai chargé un BITMAP de fichier, avec LoadImage:Comment modifier une image bitmap une fois qu'il a été chargé par win32

HBITMAP renderBMP = (HBITMAP)LoadImage(NULL, filePath, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE); 

est-il un moyen d'accéder et de modifier facilement les pixels individuellement?

Je peux l'utiliser pour obtenir l'objet bitmap, mais il ne semble pas aider,

BITMAP bm; 
GetObject(renderBMP, sizeof(bm), &bm); 

parce que la valeur de bmBits dans la structure est 0.

MISE À JOUR:

maintenant, je reçois un bug avec cette solution:

struct Pixel { unsigned char r,g,b,a; }; 
void Frame::PushMemory(HDC hdc) 
{ 
    BITMAPINFO bi; 
    ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER)); 
    bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 

    GetDIBits(hdc, renderBMP, 0, bi.bmiHeader.biHeight, NULL, &bi, DIB_RGB_COLORS); 

    /* Allocate memory for bitmap bits */ 
    Pixel* pixels = new Pixel[bi.bmiHeader.biHeight * bi.bmiHeader.biWidth]; 
    int n = sizeof(Pixel) * bi.bmiHeader.biHeight * bi.bmiHeader.biWidth; 
    int m = bi.bmiHeader.biSizeImage; 
    GetDIBits(hdc, renderBMP, 0, bi.bmiHeader.biHeight, pixels, &bi, DIB_RGB_COLORS); 

    // Recompute the output 
    //ComputeOutput(pixels); 

    // Push back to windows 
    //SetDIBits(hdc, renderBMP, 0, bi.bmiHeader.biHeight, pixels, &bi, DIB_RGB_COLORS); 

    //delete pixels; 
} 

Je reçois cette erreur:

Échec de vérification de l'exécution # 2 - La pile autour de la variable 'bi' était corrompue.

Les trois dernières lignes ne semblent pas avoir d'importance qu'elles soient commentées ou non.

Répondre

3

Utilisez GetDIBits pour accéder aux pixels. Il copie tous les pixels dans le tampon spécifié. Après modification des pixels, vous pouvez utiliser SetDIBits pour réécrire les pixels en mode point.

EDIT: Exemple de code:

LPVOID lpvBits=NULL; // pointer to bitmap bits array 
BITMAPINFO bi; 

ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER)); 
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 

if (!GetDIBits(hDC, hBmp, 0, height, NULL, &bi, DIB_RGB_COLORS)) 
    return NULL; 

/* Allocate memory for bitmap bits */ 
if ((lpvBits = new char[bi.bmiHeader.biSizeImage]) == NULL) 
    return NULL; 

if (!GetDIBits(hDC, hBmp, 0, height, lpvBits, &bi, DIB_RGB_COLORS)) 
    return NULL; 


/* do something with bits */ 


::SetDIBits(hDC, hBmp, 0, height, (LPVOID)lpvBits, &bi, DIB_RGB_COLORS); 
+0

Quand vous dites init BITMAPINFO qu'est-ce que je suis supposé faire avec ça? Que ferais-je exactement si je voulais lire dans un fichier Bitmap depuis le fichier et ensuite changer chaque pixel pour dire ... noir. comment ferais-je cela? –

+0

@gamernb: J'ai mis à jour le code un peu – DReJ

+0

Vous avez une erreur avec la solution. Voir au dessus. –

0

Si vous passez le drapeau LR_CREATEDIBSECTION à LoadImage il crée un type particulier de bitmap avec une section de mémoire usermode contenant les bits du bitmap. GetObject sur un bitmap DIBSection remplira le pointeur bmPits de la structure BITMAP, ou remplira même une structure DIBSECTION avec des données supplémentaires.