1. 打开并显示一幅位图
在OnDraw()函数中添加:
unsigned char* pBitmap=pDoc->m_pBitmap;
LPBITMAPINFO lpBitmapInfo=(LPBITMAPINFO)(pBitmap+14); //获得位图文件信息头指针
unsigned char* pBitmapData=pDoc->m_pTransfered; //位图数据头指针
unsigned long biHeight=((LPBITMAPINFOHEADER)lpBitmapInfo)->biHeight; //图像高度
unsigned long biWidth=((LPBITMAPINFOHEADER)lpBitmapInfo)->biWidth; //图像宽度
CRect rect;
GetClientRect(&rect); //得到客户区矩形
long originX=0,originY=0;
if((unsigned long)(rect.Width()) > biWidth) orginX=(rect.Width() – biWidth) >> 1;
if((unsigned long)(rect.Height()) > biHeight) orginY=(rect.Height() – biHeight) >> 1;
SetDIBitsToDecive(Pdc->m_hDC,originX,originY,biWidth,biHeight,0,0,0,biHeight,pBitmapData,lpBitmapInfo,DIB_RGB_COLORS); //在屏幕上输出图像
//这里注意不要将lpBitmapInfo写成lpBitmapInfoHeader, 两个结构体不一样
//在Doc类中添加虚函数OnOpenDocument(),添加如下代码:
m_strFileName=lpszPathName; //获得打开位图文件的路径
if(ReadBitmap(lpszPathName,m_pBitmap)) UapdateAllViews(NULL);
//在Doc类中添加成员函数ReadBitmap(LPCTSTR lpszPathName, unsigned char* &buffer)
FILE *file;
file=fopen(lpszPathName,”rb”);
if(!file) return FALSE;
fops_t posend, posbegin; //定义两个文件头、尾标识符
fseek(file, 0, SEEK_END); //将文件指针移到文件尾部
fgetpos(file, &posend);
fseek(file, 0, SEEK_SET); //将文件指针移到文件头部
fgetpos(file, &posbegin); //得到一个文件流的位置指示
size_t filesize = (size_t)(posend – posbegin); //得到文件大小
if(buffer = =NULL) buffer = (unsigned char*)malloc(filesize); //分配内存
if(buffer = =NULL){
AfxMessageBox(IDM_MEMORY_INSUFFICIENT,MB_OK,0);
returen FALSE; }
memset(buffer, 0, filesize); //给内存初始化为0
size_t sizeread = fread(buffer, sizeof(unsigned char), filesize, file); //读取位图数据
if(sizeread != filesize){
AfxMessageBox(IDM_READFILE_ERROR, MB_OK, 0);
free(buffer);
buffer = NULL;
fclose(file);
return FALSE; }
if( buffer[0] != ‘B’ || buffer[1] != ‘M’) { //判断是否为位图文件
AfxMessageBox(IDM_FILEFORMAT_ERROR, MB_OK, 0);
free(buffer);
buffer = NULL;
fclose(file);
return FALSE; }
fclose(file);
return TURE;
2. //针对24色位图进行裁剪 //pSrcFile 源位图 //pDestFile 目标位图文件 //rect 要拷贝的矩形区域
BOOL CropBitmap(LPCTSTR pSrcFile,LPCTSTR pDestFile,LPRECT rect)
{
CFile file;
CFileException fe;
BOOL ret=FALSE;
if(!file.Open(pSrcFile,C:modeRead,&fe))//打开源位图文件
return ret;
CFile f;
CFileException e;
if( !f.Open( pDestFile, C:modeCreate | C:modeWrite, &e ) )//要拷到的位图文件
return FALSE;
DWORD retLen=0;
DWORD dwBitsSize=file.GetLength();//文件长度
HGLOBAL hImageBuf = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,dwBitsSize);
if(!hImageBuf) {
file.Close(); //分配失败则返回
return FALSE; }
LPSTR lpImage = (LPSTR)GlobalLock(hImageBuf);
retLen=file.Read(lpImage,dwBitsSize); //将图像读入内存
if(retLen<dwBitsSize) {
if(hImageBuf!=NULL) {
GlobalUnlock (hImageBuf);
GlobalFree (hImageBuf); }
file.Close();
return FALSE; }
int len=sizeof(BITMAPFILEHEADER); //分析位图信息,
LPBITMAPFILEHEADER lpFhdr=(LPBITMAPFILEHEADER)lpImage;//文件头信息
LPBITMAPINFOHEADER lpbmpInfo = (LPBITMAPINFOHEADER)(lpImage+sizeof(BITMAPFILEHEADER));//位图头信息
int nLineBytes=0,nHeight=0,nWidth=0;
nHeight = lpbmpInfo->biHeight;//源图像高
nWidth = lpbmpInfo->biWidth; //源图像宽
int rectWidth=rect->right-rect->left;
int rectHeight=rect->bottom-rect->top;
//另外分配一块内存,存储大小为rectWidth*rectHeight的图像像素
HGLOBAL hTmpBuf = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,rectWidth*rectHeight*3);
LPSTR lpPic = (LPSTR)GlobalLock(hTmpBuf);
//每行不足4的整数位则补足
if((lpbmpInfo->biWidth)%4!=0) {
nLineBytes=lpbmpInfo->biWidth+(lpbmpInfo->biWidth)%4; }
else
nLineBytes=lpbmpInfo->biWidth;
// 拷贝原始图像到新分配的图像存储区
for(int y=0;y< nHeight;y++){
for(int x=0;x< nLineBytes;x++){
if(x>=rect->left&&x<rect->right){
if((y>=rect->top&&y<rect->bottom)){
//源图像像系指针(lpImage+lpFhdr->bfOffBits)
//+每行的字节数*3(nLineBytes*y*3)
//+现在每行的偏移量(x*3)
*lpPic=*(lpImage+lpFhdr->bfOffBits+ nLineBytes*y*3+x*3);
lpPic++;
*lpPic=*(lpImage+lpFhdr->bfOffBits+ nLineBytes*y*3+x*3+1);
lpPic++;
*lpPic=*(lpImage+lpFhdr->bfOffBits+ nLineBytes*y*3+x*3+2);
lpPic++; } } } }
lpPic=lpPic-rectWidth*rectHeight*3; //将指针移回开始位置
//存储位图 //除了高度,宽度,不改变原始图像的其它信息
lpbmpInfo->biWidth=rectWidth;
lpbmpInfo->biHeight=rectHeight;
f.Write(lpFhdr,len);//写文件头
f.Write( lpbmpInfo,sizeof(BITMAPINFOHEADER));//写位图信息
f.Write( lpPic,rectWidth*rectHeight*3);//写拷贝过来的图像像素
f.Close();
GlobalUnlock (hTmpBuf);//释放
GlobalFree (hTmpBuf);
GlobalUnlock (hImageBuf);//释放
GlobalFree (hImageBuf);
file.Close();
return TRUE; }