Hello,
I have already searched on the Internet about how to align each line of the bitmap data, so that it is displayed correctly. The lines must be a multiple of 4 Byte. I also tried to do so, however the problem still exists. As long as the image width is a multiple of 4 Byte, then it is displayed correctly otherwise, the lines are shifted against each other, so that the image is displayed corruptly ( see the attached files).
my steps to display the image are:
1) Load the image from the .bmp file
2) get its bits
3) Create and modify the BITMAPINFO struct, in order to pass it to SetStretchBltMode
4) display the image with "SetStretchBltMode"
and here is the function which displays the image data:Code:// Enable button 'Load Image' GetDlgItem(IDC_BUTTON_LOAD_IMAGE)->EnableWindow(FALSE); CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, _T("BMP Windows Bitmap|*.bmp|PNG Portable Network Graphics|*.png")); dlg.m_ofn.nFilterIndex = 1; dlg.m_ofn.lpstrTitle = _T("Search Test Image"); if(dlg.DoModal() == IDOK) { m_strFileName = dlg.GetPathName(); UpdateData(FALSE); HBITMAP hBitMap = (HBITMAP)LoadImage(NULL, m_strFileName,IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); if (NULL != hBitMap) { CBitmap bmp; bmp.Attach((HBITMAP)hBitMap); // handle you got from LoadBitmap BITMAP bitmap; bmp.GetBitmap(&bitmap); int paddedRow = TJPAD(bitmap.bmWidth*bitmap.bmBitsPixel/8); unsigned long bufferSize = bitmap.bmHeight*paddedRow; if (NULL != m_bufferBeforeCompression) { delete[] m_bufferBeforeCompression; m_bufferBeforeCompression = NULL; } m_bufferBeforeCompression = new unsigned char[bufferSize]; //::GetBitmapBits((HBITMAP)hBitMap,bufferSize,m_bufferBeforeCompression ); bmp.GetBitmapBits(bufferSize,m_bufferBeforeCompression ); // m_bufferBeforeCompression is the pointer to the raw image data m_nSizeX = bitmap.bmWidth; m_nSizeY = bitmap.bmHeight; m_nBitsPerPixel = bitmap.bmBitsPixel; // if it is a grayscale image, then only the grayscale subsampling for compression is possible if (m_nBitsPerPixel == 8) { m_cbSubsampling.SetCurSel(3); } display_frame(m_bufferBeforeCompression); ...
Code:void CVITA_MFCDlg::display_frame(unsigned char * ImageData) { // get the device handle of the picture control CDC* pdc = GetDlgItem(IDC_DISPLAY_TEST)->GetDC(); HDC hdc = pdc->m_hDC; // get the dimensions of the device window RECT rcClient; GetDlgItem(IDC_DISPLAY_TEST)->GetClientRect((LPRECT)&rcClient); INT picCtrlWidth = rcClient.right; INT picCtrlHeight = rcClient.bottom; BITMAPINFO* BmInfo; if (m_nBitsPerPixel == 8) { BmInfo = (BITMAPINFO*)alloca( sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256); for(int i=0; i<256; i++) { BmInfo->bmiColors[i].rgbRed = i; BmInfo->bmiColors[i].rgbGreen = i; BmInfo->bmiColors[i].rgbBlue = i; BmInfo->bmiColors[i].rgbReserved = 0; } } else { BmInfo = (BITMAPINFO*)alloca( sizeof(BITMAPINFO)); } BmInfo->bmiHeader.biSize = sizeof (BmInfo->bmiHeader); BmInfo->bmiHeader.biWidth = m_nSizeX; BmInfo->bmiHeader.biHeight = -m_nSizeY; BmInfo->bmiHeader.biPlanes = 1; BmInfo->bmiHeader.biBitCount = m_nBitsPerPixel; BmInfo->bmiHeader.biCompression = BI_RGB; //BmInfo->bmiHeader.biSizeImage = ((m_nSizeX * m_nBitsPerPixel +31) & ~31) /8 * m_nSizeY; BmInfo->bmiHeader.biSizeImage = m_nSizeY * TJPAD(m_nSizeX*m_nBitsPerPixel/8); BmInfo->bmiHeader.biClrUsed = 0; BmInfo->bmiHeader.biClrImportant = 0; // use HALFTONE or MAXSTRETCHBLTMODE stretch mode, otherwise there are some artifacts within the image SetStretchBltMode(hdc,HALFTONE); // display the content of the array on an output device and stretch the image accordingly to the device window dimensions ::StretchDIBits( hdc, // hDC 0, // DestX 0, // DestY picCtrlWidth, // nDestWidth picCtrlHeight, // nDestHeight 0, // SrcX 0, // SrcY m_nSizeX, // SrcWidth m_nSizeY, // SrcHeight (LPVOID)((LPDWORD)ImageData), // lpBits (LPBITMAPINFO)BmInfo, // lpBitsInfo DIB_RGB_COLORS, // wUsage SRCCOPY); // wDwRop // make the device context free for application ReleaseDC(pdc); }Code:#define TJPAD(p) (((p)+3)&(~3))
Could you please take a look at my code and tell me what I have to change in order to avoid the strange display bahaviour. Thanks.
best regards


Reply With Quote

Bookmarks