Stretchdibits et bitmapinfoheader

brosse_adan Messages postés 30 Date d'inscription jeudi 22 avril 2004 Statut Membre Dernière intervention 7 octobre 2005 - 8 nov. 2004 à 01:41
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 - 10 nov. 2004 à 17:45
bonjour à tous!

voilà, ça fait des heures que je suis dessus, mais là, c 'est définitif, je n'arrive pas à utiliser la fonction stretchdibits!!

cela vient sûrement de ma BITMAPINFO qui est peut-être mal rempli?? je ne comprends pas du tout à quoi sert le membre bmicolors, la documentation microsoft étant tellement claire la-dessus... :) (ou alors, et je pense que c'est ça, c'est moi qui sui bête!! :))

tout ce que je veux, c'est afficher un pauvre truc (bah oui, avant d'afficher de belles choses, fo faire simple!) en 24 bits, mais alors rien a faire, ça ne marche pas!

quelqu'un peut-il m'aider??

merci d'avance à la bonne âme qui saura me renseigner!!!

#include <windows.h>
#define APPNAME "SIW"
#define CAPTION "SIW - Essai"

struct RGBTrip {
unsigned char _r;
unsigned char _g;
unsigned char _b;
};

// les infos pour notre "image"
unsigned char g_data[100*100*3];
BITMAPINFO myBitmapInfo;

long WINAPI WindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam) {
PAINTSTRUCT ps;
HDC hDc;

switch(message) {
case WM_PAINT:
hDc = BeginPaint(hWnd, &ps);

StretchDIBits(
hDc,
20, 20,
100, 100,
0, 0,
100, 100,
(void *)g_data,
&myBitmapInfo,
DIB_RGB_COLORS,
SRCPAINT);

EndPaint(hWnd, &ps);
break;

case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

INT WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd) {

// initialisation et affichage de la fenêtre

myBitmapInfo.bmiHeader.biBitCount = 24;
myBitmapInfo.bmiHeader.biCompression = BI_RGB;
myBitmapInfo.bmiHeader.biHeight = 100;
myBitmapInfo.bmiHeader.biWidth = 100;
myBitmapInfo.bmiHeader.biPlanes = 1;
myBitmapInfo.bmiHeader.biSizeImage = 0;
myBitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
myBitmapInfo.bmiHeader.biClrUsed = 0;
myBitmapInfo.bmiHeader.biClrImportant = 0;

RGBTrip c = { 255, 0, 0};

for(int y = 0; y<100; y++) {
for(int x = 0; x<100; x++) {
g_data[x+y*100] = 255;
}
}

while(GetMessage(&msg, 0, 0, 0) == TRUE) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
}

13 réponses

ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
8 nov. 2004 à 08:59
ce source est-il complet où c'est juste une partie ?
il manque la création de la fenêtre.

d'autre part, il faut savoir que les lignes des bitmaps doivent âtre multiple de 4 octets. Ainsi un eligne de 75 pixels de marge en 24 bits par pixel prendra 75*24=1800 bits = 225 octets. Comme en mémoire les lignes doivent être alignées sur 4 octet, chaque ligne prendra en fait 228 octets (3 octets de padding).
0
brosse_adan Messages postés 30 Date d'inscription jeudi 22 avril 2004 Statut Membre Dernière intervention 7 octobre 2005
8 nov. 2004 à 09:44
non non, il n'est pas complet, la création de fenêtre est mise en commentaire!! :)

il y a juste cela à faire? mettre les lignes par multiple de 4 et c'est tout??
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
8 nov. 2004 à 09:58
non car avec 100 comme largeur ça marche (les lignes feront 100*24 = 2400 bits = 300 octets qui est multiple de 4).

par contre g_data me semble pas initialisé entièrement.

for(int y = 0; y<100; y++)
{
for(int x = 0; x<100; x++)
{
g_data[3*x+3*y*100] = 255;
g_data[3*x+3*y*100+1] = 0;
g_data[3*x+3*y*100+2] = 0;
}
}

devrait être mieux.
0
brosse_adan Messages postés 30 Date d'inscription jeudi 22 avril 2004 Statut Membre Dernière intervention 7 octobre 2005
8 nov. 2004 à 14:02
bah écoute, je vais essayer, mais tu ne penses pas que meme si mon tableau g_data n'est pas parfaitement rempli, ça devrait quand meme m'afficher quelque chose??? meme si ma couleur est pas celle que je veux, ça devrait quand meme afficher quelque chose???
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
8 nov. 2004 à 14:16
SRCCOPY au lieu de SRCPAINT en dernier param. sinon, pourrais-tu mettre la partie création de fenêtre en plus pour que je teste le code en entier.
0
brosse_adan Messages postés 30 Date d'inscription jeudi 22 avril 2004 Statut Membre Dernière intervention 7 octobre 2005
8 nov. 2004 à 15:57
je te remercie de t'intéresser autant à mon problème!

voilà donc le code, avec les quelques modifications suggérées, mais ça marche toujours pas!!! :(

#include <windows.h>
#define APPNAME "SIW"
#define CAPTION "SIW - Essai"

struct RGBTrip {
unsigned char _r;
unsigned char _g;
unsigned char _b;
};

// les infos pour notre "image"
RGBTrip g_data[100*100];
BITMAPINFO myBitmapInfo;

long WINAPI WindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam) {
PAINTSTRUCT ps;
HDC hDc;

switch(message) {
case WM_PAINT:
hDc = BeginPaint(hWnd, &ps);

StretchDIBits(
hDc,
20, 20,
100, 100,
0, 0,
100, 100,
(void *)g_data,
&myBitmapInfo,
DIB_RGB_COLORS,
SRCCOPY);

EndPaint(hWnd, &ps);
break;

case WM_DESTROY:
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

INT WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd) {

WNDCLASS wc;

HWND hwnd;
MSG msg;

wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
wc.lpszMenuName = 0;
wc.lpszClassName = APPNAME;

RegisterClass(&wc);

hwnd = CreateWindow(
APPNAME,
CAPTION,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
hInstance,
0);

ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd);

myBitmapInfo.bmiHeader.biBitCount = 24;
myBitmapInfo.bmiHeader.biCompression = BI_RGB;
myBitmapInfo.bmiHeader.biHeight = 100;
myBitmapInfo.bmiHeader.biWidth = 100;
myBitmapInfo.bmiHeader.biPlanes = 1;
myBitmapInfo.bmiHeader.biSizeImage = 0;
myBitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
myBitmapInfo.bmiHeader.biClrUsed = 0;
myBitmapInfo.bmiHeader.biClrImportant = 0;

RGBTrip c = { 255, 0, 0};

for(int y = 0; y<100; y++) {
for(int x = 0; x<100; x++) {
g_data[x+y*100] = c;
}
}

while(GetMessage(&msg, 0, 0, 0) == TRUE) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
}
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
8 nov. 2004 à 17:36
qqs petites correction :

- ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd);
doit être mis après l'init de la structure de BITMAPINFO (sinon la première fois que WM_PAINT sera reçu la structure ne sera pas bonne mais après le bitmap s'affiche, (aprè masquage de la fenêtre)

- il vaut mieux utiliser un tableau de BYTE (unsigned char) et manipuler les composantes directement par 3 (24 bits par pixels) comme dans ma réponse précédente.

- en utilisant une structure avec seulement 3 octets, le compilo va par défaut en rajouter un de plus pour aligner les données => au final ton tableau aura 4 octets (32 bits) par pixels. dans ce cas 2 choix :
* passer effectivement en 32 bits/pixel dans BITMAPINFO.
* aligner la structure sur 1 octets :
#include
struct RGBTrip {
unsigned char _b;
unsigned char _g;
unsigned char _r;
};
#include

si tu garde un alignement des structures sur 4 octets (32 bits par pixels) la structure devient :
struct RGBTrip {
unsigned char _b;
unsigned char _g;
unsigned char _r;
unsigned char _dummy;
};

dans ce cas la manipulation des pixels est facilitée car tous est bien aligné en mémoire et tout le monde est content .
0
gagah1 Messages postés 509 Date d'inscription samedi 28 juin 2003 Statut Membre Dernière intervention 3 août 2010
9 nov. 2004 à 09:36
J'ai remarqué que le membre
bmiHeader.biSizeImage = 0; alors que ceci doit être la taille de l'image en octets.
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
9 nov. 2004 à 10:07
en mettant bmiHeader.biSizeImage = 0, la taille de l'image est automatiquement calculée à partir de la la taille et le nombre de bits/pixel (image non compressée).
0
gagah1 Messages postés 509 Date d'inscription samedi 28 juin 2003 Statut Membre Dernière intervention 3 août 2010
9 nov. 2004 à 11:38
Je suis d'accord, c'est vrai !
0
brosse_adan Messages postés 30 Date d'inscription jeudi 22 avril 2004 Statut Membre Dernière intervention 7 octobre 2005
10 nov. 2004 à 17:32
Merci à tous pour vos aides, et désolé de pas avoir répondu plus tôt, j'ai des gros soucis avec mon pc!!!

alors j'ai essayé tout ce qui a été dit, mais ça marche toujours pas!!!! :( est-ce que mon code marche chez vous???

encore un gros gros merci!
0
brosse_adan Messages postés 30 Date d'inscription jeudi 22 avril 2004 Statut Membre Dernière intervention 7 octobre 2005
10 nov. 2004 à 17:43
En fait c'est bon!!! ça y est, ça marche enfin!!!

mon erreur venait du fait que j'avais pas bien corrigé!!! ;p en fait, ymca2003, t'avais raison, fallait que je modifie mon g_data avant le showwindow et le updatewindow!!! c tout bête, mais j'y avais pas du tout penser!!!

merci à tous!!! reste plus qu'à refaire marcher mon ordi en attendant celui que j'ai commandé, mais c pas gagné!!! :)
0
ymca2003 Messages postés 2070 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 3 juillet 2006 7
10 nov. 2004 à 17:45
ce code dessine un carré rouge chez moi

#include <windows.h>
#define APPNAME "SIW"
#define CAPTION "SIW - Essai"

#include 
struct RGBTrip {
unsigned char _b;
unsigned char _g;
unsigned char _r;
//unsigned char _dummy;
};
#include 

// les infos pour notre "image"
RGBTrip g_data[100*100];
BITMAPINFO myBitmapInfo;

long WINAPI WindowProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hDc;

switch(message)
{
case WM_PAINT:
{
hDc = BeginPaint(hWnd, &ps);

BOOL res=StretchDIBits(hDc, 20, 20, 100, 100, 0, 0, 100, 100,
(void *)g_data, &myBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
   LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASS wc;
HWND hwnd;
MSG msg;

wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = 0;
wc.lpszClassName = APPNAME;
RegisterClass(&wc);

hwnd = CreateWindow(APPNAME, CAPTION, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
0, 0, hInstance, 0);

memset(&myBitmapInfo, 0, sizeof(myBitmapInfo));
myBitmapInfo.bmiHeader.biBitCount = 24;
myBitmapInfo.bmiHeader.biCompression = BI_RGB;
myBitmapInfo.bmiHeader.biHeight = 100;
myBitmapInfo.bmiHeader.biWidth = 100;
myBitmapInfo.bmiHeader.biPlanes = 1;
myBitmapInfo.bmiHeader.biSizeImage = 0;
myBitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
myBitmapInfo.bmiHeader.biClrUsed = 0;
myBitmapInfo.bmiHeader.biClrImportant = 0;

RGBTrip c = { 0, 0, 255};

for(int y = 0; y<100; y++)
{
for(int x = 0; x<100; x++)
{
g_data[x+y*100] = c;
}
}

ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd);

while(GetMessage(&msg, 0, 0, 0) == TRUE)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
} 
0
Rejoignez-nous