圖片文件是有固定格式的,像BMP圖片:文件頭+位圖的顏色數據。
文件頭一般在讀取的時候是使用下面的代碼:
BITMAPFILEHEADER fileheader={0}; fread(&fileheader,sizeof(fileheader),1,fp); if(fileheader.bfType!=0x4D42) // 判斷是否為BMP圖片 { fclose(fp); return ; } BITMAPINFOHEADER head; fread(&head,sizeof(BITMAPINFOHEADER),1,fp); long bmpWidth = head.biWidth; //獲取圖片的寬 long bmpHeight = head.biHeight; //獲取圖片的寬 WORD biBitCount = head.biBitCount; if(biBitCount != 24) // 是否為24位位圖 { ::AfxMessageBox(_T("請選擇24位位圖!")); fclose(fp); return ; }
文件讀到這里了就要讀到位圖的顏色數據了,那么在讀取前,我們需要知道數據的大小,這樣才能把分配具體大學的緩沖區,之后把數據完整的讀取到緩沖區內。
那么計算位圖數據的大小一般用下面的代碼去做。
int totalSize = (bmpWidth *biBitCount/8+3)/4*4*bmpHeight; BYTE *pBmpBuf = new BYTE[totalSize];
在這些工作做完之后,我們就使用fread命令直接讀取文件內容即可,直到讀到文件結束。
整個具體的代碼實現如下
FILE *fp=NULL; int ret = fopen_s(&fp,"D:\\11.bmp","rb"); if(fp==0) { return ; } BITMAPFILEHEADER fileheader={0}; fread(&fileheader,sizeof(fileheader),1,fp); if(fileheader.bfType!=0x4D42) { fclose(fp); return ; } BITMAPINFOHEADER head; fread(&head,sizeof(BITMAPINFOHEADER),1,fp); long bmpWidth = head.biWidth; long bmpHeight = head.biHeight; WORD biBitCount = head.biBitCount; if(biBitCount != 24) { ::AfxMessageBox(_T("請選擇24位位圖!")); fclose(fp); return ; } int totalSize = (bmpWidth *biBitCount/8+3)/4*4*bmpHeight; BYTE *pBmpBuf = new BYTE[totalSize]; size_t size = 0; while(true) { int iret = fread(&pBmpBuf[size],1,1,fp); if(iret == 0) break; size = size + iret; } fclose(fp); int i,j; CClientDC dc(this); int pitch=bmpWidth%4; for(i=0;i<bmpHeight;i++) { int realPitch=i*pitch; for(j=0;j<bmpWidth;j++) { dc.SetPixel(j,i,RGB( pBmpBuf[(i*bmpWidth+j)*3+2+realPitch], pBmpBuf[(i*bmpWidth+j)*3+1+realPitch], pBmpBuf[(i*bmpWidth+j)*3+realPitch])); } } delete [] pBmpBuf; pBmpBuf = NULL; return ;