case WM_COMMAND: iConvert = 0 ; switch (LOWORD (wParam)) { case IDM_FILE_OPEN: // Show the File Open dialog box if (!GetOpenFileName (&ofn)) return 0 ;
// If there's an existing DIB and palette, delete them SendMessage (hwnd, WM_USER_DELETEDIB, 0, 0) ;
HANDLE hFile; int n; n=Bmpname.Replace("\\", "\\\\");
// Open the existing file.
hFile = CreateFile( Bmpname, // open the BitMap file GENERIC_READ, 0, // not share NULL, // no security OPEN_EXISTING, // existing file only FILE_ATTRIBUTE_NORMAL, // normal file NULL); // no attr. template //fail to open file if (hFile == INVALID_HANDLE_VALUE) { return NULL; }
BITMAPFILEHEADER bmfHeader; DWORD nFileLen,dwBytesRead; nFileLen = GetFileSize (hFile, NULL) ; //get the length of the file // Read file header if(!ReadFile(hFile, (LPSTR)&bmfHeader, sizeof(bmfHeader), &dwBytesRead, NULL) || dwBytesRead != sizeof(bmfHeader)) return NULL; // File type should be 'BM' if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B')) return NULL; HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nFileLen); if (hDIB == 0) return NULL; // Read the remainder of the bitmap file. if(!ReadFile(hFile, (LPSTR)hDIB, nFileLen - sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL) || dwBytesRead != nFileLen - sizeof(BITMAPFILEHEADER)) { ::GlobalFree(hDIB); return NULL; } BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ; //nColors is the factual color num int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed : 1 << bmInfo.bmiHeader.biBitCount; // Create the palette UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors); LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300; //version number pLP->palNumEntries = nColors;
//create color matrix for( int i=0; i < nColors; i++) { pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed; pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen; pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue; pLP->palPalEntry[i].peFlags = 0; } pPal->CreatePalette( pLP ); delete[] pLP; CloseHandle(hFile);// Close the files. return hDIB; }bool CBitMapOpView::DrawDIB( CDC* pDC, HGLOBAL hDIB, CPalette *pPal ) { LPVOID lpDIBBits; // Pointer to DIB bits bool bsuccess = false; //Check hDIB,if hDIB is null,exit the function if(hDIB == NULL) return bsuccess; BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
//nColors is the factual color num int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed : 1 << bmInfo.bmiHeader.biBitCount;
//16 bit or 24 bit or 32 bit clearly color if( bmInfo.bmiHeader.biBitCount > 8 ) lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) + ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
//Other color else lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
http://asp.6to23.com/iseesoft/devdoc/imgdoc/bmp_fileformat.htm
iConvert = 0 ; switch (LOWORD (wParam))
{
case IDM_FILE_OPEN: // Show the File Open dialog box if (!GetOpenFileName (&ofn))
return 0 ;
// If there's an existing DIB and palette, delete them SendMessage (hwnd, WM_USER_DELETEDIB, 0, 0) ;
// Load the DIB into memory SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
ShowCursor (TRUE) ; hdib = DibFileLoad (szFileName) ; ShowCursor (FALSE) ;
SetCursor (LoadCursor (NULL, IDC_ARROW)) ; // Reset the scroll bars SendMessage (hwnd, WM_USER_SETSCROLLS, TRUE, 0) ; // Create the palette and DDB SendMessage (hwnd, WM_USER_CREATEPAL, TRUE, 0) ; if (!hdib)
{
MessageBox (hwnd, TEXT ("Cannot load DIB file!"),
szAppName, MB_OK | MB_ICONEXCLAMATION) ;
}
InvalidateRect (hwnd, NULL, TRUE) ;
return 0 ;
上面是消息处理部分,下面是
HDIB DibFileLoad (const TCHAR * szFileName)
{
BITMAPFILEHEADER bmfh ;
BITMAPINFO * pbmi ;
BOOL bSuccess ;
DWORD dwInfoSize, dwBitsSize, dwBytesRead ;
HANDLE hFile ;
HDIB hDib ; // Open the file: read access, prohibit write access hFile = CreateFile (szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL) ; if (hFile == INVALID_HANDLE_VALUE)
return NULL ; // Read in the BITMAPFILEHEADER bSuccess = ReadFile (hFile, &bmfh, sizeof (BITMAPFILEHEADER),
&dwBytesRead, NULL) ; if (!bSuccess || (dwBytesRead != sizeof (BITMAPFILEHEADER))
|| (bmfh.bfType != * (WORD *) "BM"))
{
CloseHandle (hFile) ;
return NULL ;
}
// Allocate memory for the information structure & read it in dwInfoSize = bmfh.bfOffBits - sizeof (BITMAPFILEHEADER) ; if (NULL == (pbmi = malloc (dwInfoSize)))
{
CloseHandle (hFile) ;
return NULL ;
} bSuccess = ReadFile (hFile, pbmi, dwInfoSize, &dwBytesRead, NULL) ; if (!bSuccess || (dwBytesRead != dwInfoSize))
{
CloseHandle (hFile) ;
free (pbmi) ;
return NULL ;
}
// Create the DIB hDib = DibCreateFromInfo (pbmi) ;
free (pbmi) ; if (hDib == NULL)
{
CloseHandle (hFile) ;
return NULL ;
}
// Read in the bits dwBitsSize = bmfh.bfSize - bmfh.bfOffBits ; bSuccess = ReadFile (hFile, ((PDIBSTRUCT) hDib)->pBits,
dwBitsSize, &dwBytesRead, NULL) ;
CloseHandle (hFile) ; if (!bSuccess || (dwBytesRead != dwBitsSize))
{
DibDelete (hDib) ;
return NULL ;
}
return hDib ;
}
我想满足你的要求了,使用API,没有用loadimage
{
hdc = GetDC (hwnd) ; if (!(RC_PALETTE & GetDeviceCaps (hdc, RASTERCAPS)))
{
PaletteMenu (hMenu, IDM_PAL_NONE) ;
}
else if (hPalette = DibPalDibTable (hdib))
{
PaletteMenu (hMenu, IDM_PAL_DIBTABLE) ;
}
else if (hPalette = CreateHalftonePalette (hdc))
{
fHalftonePalette = TRUE ;
PaletteMenu (hMenu, IDM_PAL_HALFTONE) ;
}
ReleaseDC (hwnd, hdc) ; if ((BOOL) wParam)
hBitmap = DibCopyToDdb (hdib, hwnd, hPalette) ;
}
return 0 ; case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ; if (hPalette)
{
SelectPalette (hdc, hPalette, FALSE) ;
RealizePalette (hdc) ;
}
if (hBitmap)
{
DisplayDib (hdc,
fHalftonePalette ? DibBitmapHandle (hdib) : hBitmap,
iHscroll, iVscroll,
cxClient, cyClient,
wShow, fHalftonePalette) ;
}
EndPaint (hwnd, &ps) ;
return 0 ; case WM_QUERYNEWPALETTE:
if (!hPalette)
return FALSE ; hdc = GetDC (hwnd) ;
SelectPalette (hdc, hPalette, FALSE) ;
RealizePalette (hdc) ;
InvalidateRect (hwnd, NULL, TRUE) ; ReleaseDC (hwnd, hdc) ;
return TRUE ; case WM_PALETTECHANGED:
if (!hPalette || (HWND) wParam == hwnd)
break ; hdc = GetDC (hwnd) ;
SelectPalette (hdc, hPalette, FALSE) ;
RealizePalette (hdc) ;
UpdateColors (hdc) ; ReleaseDC (hwnd, hdc) ;
break ; case WM_DESTROY:
if (hdib)
DibDelete (hdib) ; if (hBitmap)
DeleteObject (hBitmap) ; if (hPalette)
DeleteObject (hPalette) ; PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}int DisplayDib (HDC hdc, HBITMAP hBitmap, int x, int y,
int cxClient, int cyClient,
WORD wShow, BOOL fHalftonePalette)
{
BITMAP bitmap ;
HDC hdcMem ;
int cxBitmap, cyBitmap, iReturn ; GetObject (hBitmap, sizeof (BITMAP), &bitmap) ;
cxBitmap = bitmap.bmWidth ;
cyBitmap = bitmap.bmHeight ; SaveDC (hdc) ; if (fHalftonePalette)
SetStretchBltMode (hdc, HALFTONE) ;
else
SetStretchBltMode (hdc, COLORONCOLOR) ; hdcMem = CreateCompatibleDC (hdc) ;
SelectObject (hdcMem, hBitmap) ; switch (wShow)
{
case IDM_SHOW_NORMAL:
if (fHalftonePalette)
iReturn = StretchBlt (hdc, 0, 0,
min (cxClient, cxBitmap - x),
min (cyClient, cyBitmap - y),
hdcMem, x, y,
min (cxClient, cxBitmap - x),
min (cyClient, cyBitmap - y),
SRCCOPY);
else
iReturn = BitBlt (hdc, 0, 0,
min (cxClient, cxBitmap - x),
min (cyClient, cyBitmap - y),
hdcMem, x, y, SRCCOPY) ;
break ;
case IDM_SHOW_CENTER:
if (fHalftonePalette)
iReturn = StretchBlt (hdc, (cxClient - cxBitmap) / 2,
(cyClient - cyBitmap) / 2,
cxBitmap, cyBitmap,
hdcMem, 0, 0, cxBitmap, cyBitmap, SRCCOPY);
else
iReturn = BitBlt (hdc, (cxClient - cxBitmap) / 2,
(cyClient - cyBitmap) / 2,
cxBitmap, cyBitmap,
hdcMem, 0, 0, SRCCOPY) ;
break ; case IDM_SHOW_STRETCH:
iReturn = StretchBlt (hdc, 0, 0, cxClient, cyClient,
hdcMem, 0, 0, cxBitmap, cyBitmap, SRCCOPY) ;
break ; case IDM_SHOW_ISOSTRETCH:
SetMapMode (hdc, MM_ISOTROPIC) ;
SetWindowExtEx (hdc, cxBitmap, cyBitmap, NULL) ;
SetViewportExtEx (hdc, cxClient, cyClient, NULL) ;
SetWindowOrgEx (hdc, cxBitmap / 2, cyBitmap / 2, NULL) ;
SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ; iReturn = StretchBlt (hdc, 0, 0, cxBitmap, cyBitmap,
hdcMem, 0, 0, cxBitmap, cyBitmap, SRCCOPY) ;
break ;
}
DeleteDC (hdcMem) ;
RestoreDC (hdc, -1) ;
return iReturn ;
}
我想这样应该可以了
1.你说要使用BMP文件,说明是用设备无关的DIB位图。MFC中是不提供DIB类的,
所以若要进行DIB位图的处理,最好是自己定义一个DIB类。
2.如果只是显示的话,不定义DIB类当然也没关系。
这时需要做以下件事:
1)在程序文档类中加入:
一个公有数据成员:
HANDLE m_hDIB;
说明:指向DIB数据块的内存句柄
重载以下函数:
BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if(!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
m_hDIB=LoadDIB(lpszPathName);
if(m_hDIB==NULL)
{
return FALSE;
}
SetPathName(lpszPathName);
SetModifiedFlag(FALSE);
return TRUE;
}
CMyDoc是你的程序中自动生成的DOC类
上面调用的LoadDIB函数需要自己编写
HANDLE CMyDoc::LoadDIB(LPTSTR lpFileName)
参数lpFileName---指向文件名字符串的指针
返回值HANDLE---指向DIB数据缓冲区的句柄
说明:将指定的DIB文件读入内存
这个函数的代码可以参考楼上的DibFileLoad()
他返回的HDIB应该就是一个HANDlE吧
这样就完成了文件的载入。
2)在程序视图类类中加入:
一个数据成员:
CRECT m_rectDIB;
说明:用来存储位图的位置,尺寸信息
重载以下函数:
void CMyScrollView::OnInitialUpdate()
{
CScrollView::OnInitialUpDate();
CMyDoc* pDoc=GetDocument();
ASSERT_VALID(pDoc);
CSize sizeTotal;
if(pDoc->m_hDIB!=NULL)
{
LPBITMAPINFOHEADER lpDIB=
(LPBITMAPINFOHEADER)GlobalLock(pDoc->m_hDIB);
m_rectDIB.left=0;
m_rectDIB.top=0;
sizeTotal.cx=m_rectDIB.right=
((LPBITMAPINFOHEADER)lpDIB)->biwidth;
sizeTotal.cy=m_rectDIB.bottom=
((LPBITMAPINFOHEADER)lpDIB)->biHeight;
GlobalUnlock(pDoc->m_hDIB);
}
else
{
m_rectDIB.SetRectEmpty();
sizeTotal.cx=sizeTotal.cy=100;
}
SetScrollSizes(MM_TEXT,sizeTotal);
}
说明:1这里使用CScrollView类而不是CView类是为了满足大图片的要求
2因为OninitialUpdate函数会在文件装入后自动被调用,所以可在
这儿进行一些预处理
void CMyScrollView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc=GetDocument();
ASSERT_VALID(pDoc);
if(pDoc->m_hDIB==NULL)
return;
PaintDIB(pDC->GetSafeHdc(),m_rectDIB,pDoc->m_hDIB,m_rectDIB,
NULL,SRCCOPY);
说明:
PaintDIB需自己编写,定义如下:
BOOL CMyScrollView::PaintDIB(HDC hDC,LPRECT lpDCRect,HANDLE hDIB,
LPRECT lpDIBRect,HPALETTE hPal,DWORD dwRop)
参数:
hDC---显示DIB的设备上下文句柄
lpDCRect---设备中显示DIB的矩形区域
dDIB---存储DIB数据缓冲区的内存块句柄
lpDIBRect---要显示的DIB矩形区域
hPal---用以显示DIB的调色板句柄
dwRop---显示DIB的ROP模式
具体可参考楼上的DisplayDib()函数
这样就可以完成图形显示
但还有一个问题:
就是我们还没对调色板进行处理,所以显示的图像不一定符合要求。
(系统调色板只有20色)调色板的问题下次再交流吧。3.如果你有什么好的资料和原码,希望也可以提供给我。谢谢。
最后推荐你一本书---周长发的<<visual c++.net图像处理编程>>
上边有不少图形处理算法。
HGLOBAL CBitMapOpView::LoadBMP( CPalette *pPal )
{
HANDLE hFile;
int n;
n=Bmpname.Replace("\\", "\\\\");
// Open the existing file.
hFile = CreateFile( Bmpname, // open the BitMap file
GENERIC_READ,
0, // not share
NULL, // no security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template //fail to open file
if (hFile == INVALID_HANDLE_VALUE)
{
return NULL;
}
BITMAPFILEHEADER bmfHeader;
DWORD nFileLen,dwBytesRead;
nFileLen = GetFileSize (hFile, NULL) ; //get the length of the file
// Read file header
if(!ReadFile(hFile, (LPSTR)&bmfHeader, sizeof(bmfHeader), &dwBytesRead, NULL) ||
dwBytesRead != sizeof(bmfHeader))
return NULL;
// File type should be 'BM'
if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B'))
return NULL; HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nFileLen);
if (hDIB == 0)
return NULL; // Read the remainder of the bitmap file.
if(!ReadFile(hFile, (LPSTR)hDIB, nFileLen - sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL) ||
dwBytesRead != nFileLen - sizeof(BITMAPFILEHEADER))
{
::GlobalFree(hDIB);
return NULL;
} BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ; //nColors is the factual color num
int nColors = bmInfo.bmiHeader.biClrUsed ?
bmInfo.bmiHeader.biClrUsed : 1 << bmInfo.bmiHeader.biBitCount;
// Create the palette UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300; //version number
pLP->palNumEntries = nColors;
//create color matrix
for( int i=0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
} pPal->CreatePalette( pLP );
delete[] pLP;
CloseHandle(hFile);// Close the files.
return hDIB;
}bool CBitMapOpView::DrawDIB( CDC* pDC, HGLOBAL hDIB, CPalette *pPal )
{
LPVOID lpDIBBits; // Pointer to DIB bits
bool bsuccess = false; //Check hDIB,if hDIB is null,exit the function
if(hDIB == NULL)
return bsuccess; BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
//nColors is the factual color num
int nColors = bmInfo.bmiHeader.biClrUsed ?
bmInfo.bmiHeader.biClrUsed : 1 << bmInfo.bmiHeader.biBitCount;
//16 bit or 24 bit or 32 bit clearly color
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors +
bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
//Other color
else
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
// select the palette into a device context and realize it
if( pPal && (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) )
{
pDC->SelectPalette(pPal, FALSE);
pDC->RealizePalette();
} //draw bmp
::SetDIBitsToDevice(pDC->m_hDC, // hDC
0, // DestX
0, // DestY
bmInfo.bmiHeader.biWidth, // nDestWidth
bmInfo.bmiHeader.biHeight, // nDestHeight
0, // SrcX
0, // SrcY
0, // nStartScan
bmInfo.bmiHeader.biHeight, // nNumScans
lpDIBBits, // lpBits
(LPBITMAPINFO)hDIB, // lpBitsInfo
DIB_RGB_COLORS); // wUsage bsuccess = true;
return bsuccess;
}
{
FILE *fp;
BITMAPFILEHEADER bf;
LPBITMAPINFOHEADER lpbi;
DWORD dwImgSize;
int w,h; if((fp=fopen(strFileName,"rb"))==NULL)
{
AfxMessageBox("File open error");
return FALSE;
}
fread(&bf,1,14,fp);
dwImgSize=bf.bfSize-14;
lpbi=(LPBITMAPINFOHEADER)malloc(dwImgSize);
fread(lpbi,1,dwImgSize,fp);
fclose(fp);
lpbi->biCompression=0;
w=dxDst;
h=dyDst;
if(lpbi->biWidth<dxDst) w=lpbi->biWidth;
if(lpbi->biHeight<dxDst) h=lpbi->biHeight;
HDRAWDIB hdd;
hdd=DrawDibOpen();
if(hdd==NULL)
return FALSE;
if(!DrawDibDraw(hdd,hdc,0,0,w,h,lpbi,NULL,0,0,lpbi->biWidth,lpbi->biHeight,NULL))
{
AfxMessageBox("DrawDibDraw error");
DrawDibClose(hdd);
return FALSE;
}
DrawDibClose(hdd);
return TRUE;
}
example:
/* HDC hdc=::GetDC(GetSafeHwnd());
ShowBmp(hdc,"f:\\test1.bmp",0,0,384/3,288/3);
::ReleaseDC(GetSafeHwnd(),hdc);
*/