Enregistrement du fichier .bmp à l’aide de hBitmap = CreateDIBSection () dans C Win32

J’ai le code suivant. Je souhaite utiliser ces informations pour créer un fichier .bmp qui affiche les données de la mémoire, qui est une image copiée depuis un framegrabber dans la mémoire principale. Quelqu’un peut-il me laisser s’il vous plaît? Je vous remercie

LPSTR CreateBMP( HWND hAppWnd, int nImageType ) 

{
void * pWinGBits = NULL; int i; Z_BITMAPINFO zWinGHeader; // bitmapinfo pour la certificateion de la DIB

 // create DC for bitmap. hDCBits = CreateCompatibleDC( ghDCMain ); switch ( nImageType ) { case bayer_filter: zWinGHeader.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); zWinGHeader.bmiHeader.biPlanes = 1; zWinGHeader.bmiHeader.biClrImportant = 0; zWinGHeader.bmiHeader.biHeight = -lYSize; zWinGHeader.bmiHeader.biWidth = lXSize; zWinGHeader.bmiHeader.biBitCount = 32; zWinGHeader.bmiHeader.biClrUsed = 0;//3; zWinGHeader.bmiHeader.biCompression = BI_BITFIELDS; zWinGHeader.bmiHeader.biSizeImage = 0; zWinGHeader.bmiColors[0].rgbBlue = 0x00; zWinGHeader.bmiColors[0].rgbGreen = 0x00; zWinGHeader.bmiColors[0].rgbRed = 0xFF; zWinGHeader.bmiColors[0].rgbReserved = 0x00; zWinGHeader.bmiColors[1].rgbBlue = 0x00; zWinGHeader.bmiColors[1].rgbGreen = 0xFF; zWinGHeader.bmiColors[1].rgbRed = 0x00; zWinGHeader.bmiColors[1].rgbReserved = 0x00; zWinGHeader.bmiColors[2].rgbBlue = 0xFF; zWinGHeader.bmiColors[2].rgbGreen = 0x00; zWinGHeader.bmiColors[2].rgbRed = 0x00; zWinGHeader.bmiColors[2].rgbReserved = 0x00; break; case color32: zWinGHeader.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); zWinGHeader.bmiHeader.biPlanes = 1; zWinGHeader.bmiHeader.biClrImportant = 0; zWinGHeader.bmiHeader.biHeight = -lYSize; zWinGHeader.bmiHeader.biWidth = lXSize/4; zWinGHeader.bmiHeader.biBitCount = 32; zWinGHeader.bmiHeader.biClrUsed = 0; zWinGHeader.bmiHeader.biCompression = BI_BITFIELDS; zWinGHeader.bmiHeader.biSizeImage = 0; zWinGHeader.bmiColors[0].rgbBlue = 0x00; zWinGHeader.bmiColors[0].rgbGreen = 0x00; zWinGHeader.bmiColors[0].rgbRed = 0xFF; zWinGHeader.bmiColors[0].rgbReserved = 0x00; zWinGHeader.bmiColors[1].rgbBlue = 0x00; zWinGHeader.bmiColors[1].rgbGreen = 0xFF; zWinGHeader.bmiColors[1].rgbRed = 0x00; zWinGHeader.bmiColors[1].rgbReserved = 0x00; zWinGHeader.bmiColors[2].rgbBlue = 0xFF; zWinGHeader.bmiColors[2].rgbGreen = 0x00; zWinGHeader.bmiColors[2].rgbRed = 0x00; zWinGHeader.bmiColors[2].rgbReserved = 0x00; break; case color24: zWinGHeader.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); zWinGHeader.bmiHeader.biPlanes = 1; zWinGHeader.bmiHeader.biClrImportant = 0; zWinGHeader.bmiHeader.biHeight = -lYSize; zWinGHeader.bmiHeader.biWidth = lXSize/3; zWinGHeader.bmiHeader.biBitCount = 24; zWinGHeader.bmiHeader.biClrUsed = 0; zWinGHeader.bmiHeader.biCompression = BI_RGB; zWinGHeader.bmiHeader.biSizeImage = 0; break; case color3x16: zWinGHeader.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); zWinGHeader.bmiHeader.biPlanes = 1; zWinGHeader.bmiHeader.biClrImportant = 0; zWinGHeader.bmiHeader.biHeight = -lYSize; zWinGHeader.bmiHeader.biWidth = lXSize/6; zWinGHeader.bmiHeader.biBitCount = 32; zWinGHeader.bmiHeader.biClrUsed = 0; zWinGHeader.bmiHeader.biCompression = BI_BITFIELDS; zWinGHeader.bmiHeader.biSizeImage = 0; zWinGHeader.bmiColors[0].rgbBlue = 0x00; zWinGHeader.bmiColors[0].rgbGreen = 0x00; zWinGHeader.bmiColors[0].rgbRed = 0xFF; zWinGHeader.bmiColors[0].rgbReserved = 0x00; zWinGHeader.bmiColors[1].rgbBlue = 0x00; zWinGHeader.bmiColors[1].rgbGreen = 0xFF; zWinGHeader.bmiColors[1].rgbRed = 0x00; zWinGHeader.bmiColors[1].rgbReserved = 0x00; zWinGHeader.bmiColors[2].rgbBlue = 0xFF; zWinGHeader.bmiColors[2].rgbGreen = 0x00; zWinGHeader.bmiColors[2].rgbRed = 0x00; zWinGHeader.bmiColors[2].rgbReserved = 0x00; break; case bw1x10: // create bitmap-infoheader. zWinGHeader.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); zWinGHeader.bmiHeader.biPlanes = 1; zWinGHeader.bmiHeader.biBitCount = 8; zWinGHeader.bmiHeader.biCompression = BI_RGB; zWinGHeader.bmiHeader.biSizeImage = 0; zWinGHeader.bmiHeader.biClrUsed = 256; zWinGHeader.bmiHeader.biClrImportant= 0; zWinGHeader.bmiHeader.biHeight = -lYSize; zWinGHeader.bmiHeader.biWidth = lXSize/2; // create colortable fot bitmap (grayvalues). for (i = 0; i < 256; i++) { zWinGHeader.bmiColors[i].rgbGreen = i; zWinGHeader.bmiColors[i].rgbBlue = i; zWinGHeader.bmiColors[i].rgbRed = i; zWinGHeader.bmiColors[i].rgbReserved = 0; } break; default: case bw8: // create bitmap-infoheader. zWinGHeader.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); zWinGHeader.bmiHeader.biPlanes = 1; zWinGHeader.bmiHeader.biBitCount = 8; zWinGHeader.bmiHeader.biCompression = BI_RGB; zWinGHeader.bmiHeader.biSizeImage = 0; zWinGHeader.bmiHeader.biClrUsed = 256; zWinGHeader.bmiHeader.biClrImportant= 0; zWinGHeader.bmiHeader.biHeight = -lYSize; zWinGHeader.bmiHeader.biWidth = lXSize; // create colortable fot bitmap (grayvalues). for (i = 0; i < 256; i++) { zWinGHeader.bmiColors[i].rgbGreen = i; zWinGHeader.bmiColors[i].rgbBlue = i; zWinGHeader.bmiColors[i].rgbRed = i; zWinGHeader.bmiColors[i].rgbReserved = 0; } break; } // cerate identity palette hPal = CreateIdentityPalette( zWinGHeader.bmiColors ); // get new palette into DC and map into physical palette register. hOldPal = SelectPalette( ghDCMain, hPal, FALSE); RealizePalette( ghDCMain ); // cerate DIB-Section f黵 direct access of image-data. hBitmap = CreateDIBSection( hDCBits, // handle of device context (BITMAPINFO *)&zWinGHeader, // address of structure containing // bitmap size, format and color data DIB_RGB_COLORS, // color data type indicator: RGB values // or palette indices &pWinGBits, // pointer to variable to receive a pointer // to the bitmap's bit values NULL, // optional handle to a file mapping object 0 // offset to the bitmap bit values within // the file mapping object ); // get bitmap into DC . hOldBitmap = (HBITMAP)SelectObject( hDCBits, hBitmap ); return pWinGBits; // return pointer to DIB 

}

Le moyen le plus simple de passer des données d’image en mémoire ou d’un HBITMAP à un fichier image à l’aide de l’API Win32 est d’utiliser GDI +. Créez simplement un object Bitmap à partir de vos données d’image ou de HBITMAP (voir http://msdn.microsoft.com/en-us/library/ms536314%28v=vs.85%29.aspx ), puis utilisez la méthode Save pour créer le fichier (voir http://msdn.microsoft.com/en-us/library/ms535407%28v=vs.85%29.aspx ). Si vous ne pouvez pas utiliser C ++, ces méthodes existent également en tant que fonctions appelables à partir de C.

En C, la conversion est très pénible car vous devez créer le bitmap manuellement. Voici le code que j’ai utilisé dans le passé qui faisait ça:

 PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp) { BITMAP bmp; PBITMAPINFO pbmi; WORD cClrBits; // Resortingeve the bitmap color format, width, and height. if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp)) return NULL; // Convert the color format to a count of bits. cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); if (cClrBits == 1) cClrBits = 1; else if (cClrBits <= 4) cClrBits = 4; else if (cClrBits <= 8) cClrBits = 8; else if (cClrBits <= 16) cClrBits = 16; else if (cClrBits <= 24) cClrBits = 24; else cClrBits = 32; // Allocate memory for the BITMAPINFO structure. (This structure // contains a BITMAPINFOHEADER structure and an array of RGBQUAD // data structures.) if (cClrBits != 24) pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1<< cClrBits)); // There is no RGBQUAD array for the 24-bit-per-pixel format. else pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER)); // Initialize the fields in the BITMAPINFO structure. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = bmp.bmWidth; pbmi->bmiHeader.biHeight = bmp.bmHeight; pbmi->bmiHeader.biPlanes = bmp.bmPlanes; pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; if (cClrBits < 24) pbmi->bmiHeader.biClrUsed = (1<bmiHeader.biCompression = BI_RGB; // Compute the number of bytes in the array of color // indices and store the result in biSizeImage. // For Windows NT, the width must be DWORD aligned unless // the bitmap is RLE compressed. This example shows this. // For Windows 95/98/Me, the width must be WORD aligned unless the // bitmap is RLE compressed. pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8 * pbmi->bmiHeader.biHeight; // Set biClrImportant to 0, indicating that all of the // device colors are important. pbmi->bmiHeader.biClrImportant = 0; return pbmi; } void CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC) { HANDLE hf; // file handle BITMAPFILEHEADER hdr; // bitmap file-header PBITMAPINFOHEADER pbih; // bitmap info-header LPBYTE lpBits; // memory pointer DWORD dwTotal; // total count of bytes DWORD cb; // incremental count of bytes BYTE *hp; // byte pointer DWORD dwTmp; pbih = (PBITMAPINFOHEADER) pbi; lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); if (!lpBits) return; // Resortingeve the color table (RGBQUAD array) and the bits // (array of palette indices) from the DIB. if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, DIB_RGB_COLORS)) { return; } // Create the .BMP file. hf = CreateFile(pszFile, GENERIC_READ | GENERIC_WRITE, (DWORD) 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); if (hf == INVALID_HANDLE_VALUE) return; hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" // Compute the size of the entire file. hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof(RGBQUAD) + pbih->biSizeImage); hdr.bfReserved1 = 0; hdr.bfReserved2 = 0; // Compute the offset to the array of color indices. hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof (RGBQUAD); // Copy the BITMAPFILEHEADER into the .BMP file. if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp, NULL)) { return; } // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof (RGBQUAD), (LPDWORD) &dwTmp, ( NULL))) return; // Copy the array of color indices into the .BMP file. dwTotal = cb = pbih->biSizeImage; hp = lpBits; if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) return; // Close the .BMP file. if (!CloseHandle(hf)) return; // Free memory. GlobalFree((HGLOBAL)lpBits); } //code for saving bitmap HBITMAP hBitmap; HDC hdc; ... PBITMAPINFO pBitmapInfo = CreateBitmapInfoStruct(hBitmap); CreateBMPFile(_T("c:\\temp\\picture.bmp"), pBitmapInfo, hBitmap, hdc); 

Si vous êtes autorisé à utiliser C ++, vous pouvez le faire beaucoup plus facilement (en quelques lignes) en utilisant CImage from ATL .

La fonction CreateDIBSection crée un CreateDIBSection DIB * dans lequel les applications peuvent écrire directement. La fonction vous donne un pointeur sur l’emplacement des valeurs de bit bitmap.

Cet appel ne crée pas d’ image bitmap. Pourquoi voulez-vous utiliser cette fonction?

  • Bitmap indépendant du périphérique