billgatesanonym | Il y a plusieurs types d'images BMP (je suppose qu'il s'agit du format BMP de Windows).
Il peut y avoir des images en noir et blanc, ou bien avec une palette de couleurs, ou avec 4 octets par pixel, ce qui est devenu le format le plus courant de nos jours.
Comme c'est mon jour de bonté, voici du code testé et approuvé qui permet de charger une image BMP en mémoire et d'obtenir la couleur de chaque pixel beaucoup plus rapidement qu'avec l'API GetPixel() qui marche aussi :
Code :
- #include <windows.h>
- BITMAP bmp1;
- HBITMAP hbmp1;
- BYTE *DIBits;
- HGLOBAL hDIBits;
- UINT picture_width, picture_height;
- /* ============================================================== */
- int init_bitmap(void)
- {
- hbmp1 = NULL;
- hDIBits = NULL;
- DIBits = NULL;
- picture_width = 0;
- picture_height = 0;
- return TRUE;
- }
- /* ============================================================== */
- int release_bitmaps(void)
- {
- if (hbmp1 != NULL) {
- DeleteObject(hbmp1);
- hbmp1 = NULL;
- }
- if (hDIBits != NULL) {
- GlobalUnlock(hDIBits);
- GlobalFree(hDIBits);
- hDIBits = NULL;
- DIBits = NULL;
- }
- return TRUE;
- }
- /* ==============================================================
- Load a BMP file into a DIB bitmap.
- ============================================================== */
- static int loadDIBfromBMPfile(HWND hwnd, char *bmp_filename)
- {
- BITMAPINFO bi;
- UINT width, height, components_nb;
- HDC hdc;
- HDC hdcmem; HBITMAP hbmpmem;
- int DIB_x0, DIB_y0, DIB_w;
- HBITMAP h_tmp_bmp;
- BITMAP tmp_bm;
- if (hwnd == NULL)
- return -99;
- if (hbmp1 != NULL) {
- release_bitmaps();
- init_bitmap();
- }
- DIB_x0 = 0; DIB_y0 = 0; DIB_w = 0;
- memset(&bi, 0, sizeof(BITMAPINFO));
- bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bi.bmiHeader.biPlanes = 1;
- bi.bmiHeader.biBitCount = 32; // 32 bit so no padding of the horizontal lines is required
- bi.bmiHeader.biCompression = BI_RGB;
- bi.bmiHeader.biClrUsed = 0;
- bi.bmiHeader.biClrImportant = 0;
- // Load file
- h_tmp_bmp = (HBITMAP)LoadImage(NULL, bmp_filename, IMAGE_BITMAP, 0, 0,
- LR_LOADFROMFILE);
- // LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
- GetObject(h_tmp_bmp, sizeof(BITMAP), &tmp_bm);
- // N.B.: The GetObject function returns only the width, height, and color format information of the bitmap
- DIB_w = DIB_x0 + tmp_bm.bmWidth;
- height = DIB_y0 + tmp_bm.bmHeight;
- bi.bmiHeader.biWidth = DIB_w;
- bi.bmiHeader.biHeight = -height;
- bi.bmiHeader.biSizeImage = DIB_w * 4 * height * sizeof(BYTE);
- picture_width = DIB_w;
- picture_height = height;
- // Allocate a buffer for the pixels
- hDIBits = GlobalAlloc(GHND, bi.bmiHeader.biSizeImage);
- if (hDIBits == NULL)
- return(-3);
- DIBits = (BYTE *)GlobalLock(hDIBits);
- memset(DIBits, 255, bi.bmiHeader.biSizeImage); // Initiailize with white pixels
- // Create a memory DC, with a bitmap
- hdc = GetDC(hwnd);
- if (!hdc) {
- GlobalUnlock(hDIBits); GlobalFree(hDIBits);
- hDIBits = NULL; DIBits = NULL;
- return -5;
- }
- GetDIBits(hdc, h_tmp_bmp, 0, tmp_bm.bmHeight, DIBits, &bi, DIB_RGB_COLORS);
- hbmp1 = CreateDIBitmap(hdc, &bi.bmiHeader, CBM_INIT,
- DIBits, &bi, DIB_RGB_COLORS);
- DeleteObject(h_tmp_bmp);
- ReleaseDC(hwnd, hdc);
- if (hbmp1 == NULL) {
- MessageBox(hwnd, "Image too big and/or not enough video ram.",
- "Error", MB_OK|MB_ICONERROR);
- return FALSE;
- }
- InvalidateRect(hwnd, NULL, TRUE); // Refresh screen
- return(0);
- }
- /* ================================================
- Get the color of pixel at x, y
- ================================================ */
- int get_pixel_color(int x, int y, int &blue, int &green, int &red)
- {
- long int k;
- k = (y * picture_width + x) * 4;
- *blue = DIBits[k];
- *green = DIBits[k + 1];
- *red = DIBits[k + 2];
- // The fourth integer is not used or is the alpha value
- return TRUE;
- }
|
Edit : correction pour enlever des lignes qui ne sont pas utiles dans ce cadre et qui utilisaient des variables définies ailleurs, et aussi pour rajouter #include <windows.h> qu'il faut évidemment ajouter quand on programme pour Windows en C. |