bmp文件的读取与显示代码

合集下载

完整程序_C语言对BMP图像的读和写和对像素的操作

完整程序_C语言对BMP图像的读和写和对像素的操作

#include <stdio.h>#include "Windows.h"BOOL readBmp(char *bmpName);BOOL saveBmp(char *bmpName, char *imgBuf, int width, int heigh, int biBitCount, RGBQUAD *pColorTable);char *pBmpBuf; //位图数据int bmpWidth; // 图像宽度int bmpHeight; //图像高度int biBiCount; //图像类型,每像素位数RGBQUAD *pColorTable; //位图颜色表指针int main(){char readName[] = "read.BMP";readBmp(readName);char writeName[] = "write.BMP";saveBmp(writeName, pBmpBuf, bmpWidth, bmpHeight, biBiCount, pColorTable);int lineByte = (bmpWidth*bmpHeight/8+3)/4*4;if (biBiCount == 8){for (int i = 0; i < bmpWidth/2; i++){for (int j = 0; j < bmpHeight/2; j++){*(pBmpBuf+i*lineByte+j) = 0;}}}else if (biBiCount == 24){/////对于24位真彩图,每个像素占三个字节分别存储R、G、B三个颜色分量的颜色值for (int i = 0; i < bmpWidth/2; i++){for (int j = 0; j < bmpHeight/2; j++){for (int k = 0; k < 3; k++)*(pBmpBuf+i*lineByte+j*3+k) = 0; //将rgb三个颜色分量设置成黑色}}}char Name[] = "copy.BMP";saveBmp(Name, pBmpBuf, bmpWidth, bmpHeight, biBiCount, pColorTable);delete []pBmpBuf;if (biBiCount == 8){delete []pColorTable;}return 0;}BOOL readBmp(char *bmpName ){FILE *pf = fopen(bmpName, "rb");if (pf == NULL) return FALSE;printf("read %s succeeded!\n", bmpName);fseek(pf, sizeof(BITMAPFILEHEADER), SEEK_SET);BITMAPINFOHEADER infoHeader;fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, pf);bmpWidth = infoHeader.biWidth;bmpHeight = infoHeader.biHeight;biBiCount = infoHeader.biBitCount;//图像每行的字节数,一定要是4的倍数int lineByte = (bmpWidth*bmpHeight/8+3)/4*4;pBmpBuf = new char[lineByte*bmpHeight];//灰度图像有颜色表if (biBiCount == 8){pColorTable = new RGBQUAD[256];fread(pColorTable, sizeof(RGBQUAD), 1, pf);}fread(pBmpBuf, lineByte*bmpHeight, 1, pf);fclose(pf); //关闭文件return TRUE;}BOOL saveBmp(char *bmpName, char *imgBuf, int width, int heigh, int biBitCount, RGBQUAD *pColorTable ){FILE *pf = fopen(bmpName, "wb");if (pf == NULL) return FALSE;printf("write %s succeeded!\n", bmpName);//写头文件int colorTableSize = 0;if (biBitCount == 8){colorTableSize = 1024;}int lineByte = (width*heigh/8+3)/4*4;BITMAPFILEHEADER filehead;filehead.bfOffBits = 54+colorTableSize;filehead.bfType = 0x4D42;filehead.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colorTableSize+lineByte*heig h;filehead.bfReserved1 = 0;filehead.bfReserved2 = 0;fwrite(&filehead, sizeof(BITMAPFILEHEADER), 1, pf);BITMAPINFOHEADER infoHead;infoHead.biBitCount = biBitCount;infoHead.biWidth = width;infoHead.biHeight = heigh;infoHead.biSize = 40;infoHead.biClrImportant = 0;infoHead.biSizeImage = lineByte*heigh;infoHead.biClrUsed = 0;infoHead.biPlanes = 1;infoHead.biXPelsPerMeter = 0;infoHead.biYPelsPerMeter = 0;fwrite(&infoHead,sizeof(BITMAPINFOHEADER), 1, pf);if (biBitCount == 8){fwrite(pColorTable, sizeof(RGBQUAD), 256, pf);}fwrite(pBmpBuf, lineByte*heigh, 1, pf);fclose(pf);return TRUE;}。

BMP格式图像显示程序代码

BMP格式图像显示程序代码

BMP格式图像显示程序代码参数StartX和StartY为图像在LCD显示的其实位置,pbmpfile为bitmap图像文件句柄。

//从SD卡读取每行像素的缓冲区/* fit lcd hor width, consider 32bit bmp->max */uint8_t image_data_buff[LCD_HOR_RESOLUTION * 4];//1920/******************************************************************************** * function : BSP_LCD_DrawBitmap* Description : Draws a bitmap picture* Argument(s) : StartX - LCD X position, StartY - LCD Y position, pbmpfile - Bmp picture file handler.* Return(s) : none******************************************************************************* */void BSP_LCD_DrawBitmap(uint32_t StartX, uint32_t StartY, FIL *pbmpfile){uint32_t i, j, k, bytesPerPixel, bytesPerLine, bytesread;uint32_t EndX, EndY, color;FRESULT res;BITMAP_HEADER BitMapHeader;//read bitmap headerres = f_lseek (pbmpfile, 0);res = f_read (pbmpfile, &BitMapHeader, sizeof(BITMAP_HEADER), &bytesread);if(FR_OK != res) return;//-------------------test code start - show bmp image info------------------- BSP_LCD_SetForeColor(COLOR_CODE_BLACK);BSP_LCD_FillRect(0, 0, LCD_HOR_RESOLUTION-1, 80);BSP_LCD_SetForeColor(COLOR_CODE_WHITE);BSP_LCD_Printf(0, 0 , ASCII_FONT_CODE_16x16, "bitmap image infomation:");BSP_LCD_Printf(0, 16, ASCII_FONT_CODE_16x16, "image Width:%d", BitMapHeader.bminfoHeader.biWidth);BSP_LCD_Printf(0, 32, ASCII_FONT_CODE_16x16, "image biHeight:%d", BitMapHeader.bminfoHeader.biHeight);BSP_LCD_Printf(0, 48, ASCII_FONT_CODE_16x16, "pixel BitCount:%d", BitMapHeader.bminfoHeader.biBitCount);BSP_LCD_Printf(0, 64, ASCII_FONT_CODE_16x16, "Compression:%d", BitMapHeader.bminfoHeader.biCompression);//-------------------test code end - show bmp image info-------------------if(0x4D42 != BitMapHeader.bmfileHeader.bfType) return;if(BitMapHeader.bminfoHeader.biBitCount < 16) return;if(1==BitMapHeader.bminfoHeader.biCompression || 2==BitMapHeader.bminfoHeader.biCompression) return;//LCD Set WindowsEndX = StartX + BitMapHeader.bminfoHeader.biWidth - 1;EndY = StartY + BitMapHeader.bminfoHeader.biHeight - 1;if(EndX >= LCD_HOR_RESOLUTION) EndX = LCD_HOR_RESOLUTION-1;if(EndY >= LCD_VER_RESOLUTION) EndY = LCD_VER_RESOLUTION-1;//note - count of image data every line must be multiple of 4 bytesbytesPerPixel = BitMapHeader.bminfoHeader.biBitCount / 8;bytesPerLine = bytesPerPixel * BitMapHeader.bminfoHeader.biWidth;if(bytesPerLine % 4) bytesPerLine = bytesPerLine + 4 - (bytesPerLine % 4);/* Prepare to write GRAM *///set display direction, because bmp image is invertedBSP_LCD_Set_WriteDir(LCDWriteDir_L2R_D2U);//Set WindowsBSP_LCD_SetWindows(StartX, StartY, EndX, EndY);//start write gui ramBSP_LCD_WriteCmd(lcd_device.WriteRamCmd);for(j = StartY; j <= EndY; j++) {//new linek = BitMapHeader.bmfileHeader.bfOffBits + bytesPerLine * (j-StartY);res = f_lseek (pbmpfile, k);#if 1//条件选择:使用大数组uint8_t image_data_buff[LCD_HOR_RESOLUTION * 4]作为缓冲区//---------------------------large ram buffer start--------------------------- //every time read one line pixelsk = bytesPerPixel * BitMapHeader.bminfoHeader.biWidth;res = f_read(pbmpfile, image_data_buff, k, &bytesread);//err or no more dataif(FR_OK!=res || 0==bytesread){BSP_LCD_Set_WriteDir(LCDWriteDir_L2R_U2D);//restore display directionreturn;}//display pixelsk = 0;for(i = StartX; i <= EndX; i++, k++){//color - combine RGBif(32 == BitMapHeader.bminfoHeader.biBitCount){color = (image_data_buff[4*k])>>3; //Bcolor += ((uint16_t)(image_data_buff[4*k+1])<<3) & 0x07E0; //Gcolor += ((uint16_t)(image_data_buff[4*k+2])<<8) & 0xF800; //R }else if(24 == BitMapHeader.bminfoHeader.biBitCount){color = (image_data_buff[3*k])>>3; //Bcolor += ((uint16_t)(image_data_buff[3*k+1])<<3) & 0x07E0; //Gcolor += ((uint16_t)(image_data_buff[3*k+2])<<8) & 0xF800; //R }else if(0 == BitMapHeader.bminfoHeader.biCompression){//RGB 555 - BI_RGBcolor = ((uint16_t)image_data_buff[2*k] & 0x1F); //Rcolor += ((uint16_t)image_data_buff[2*k] & 0xE0)<<1; //Gcolor += ((uint16_t)image_data_buff[2*k+1])<<9;//R,G}else{//RGB 565color = image_data_buff[2*k];//G,Bcolor += ((uint16_t)image_data_buff[2*k+1])<<8;//R,G}//write LCDBSP_LCD_WriteData(color);//Write 16-bit GRAM}//----------------------------large ram buffer end---------------------------- #else//条件选择:使用小数组uint8_t pdata[128]作为图像数据缓冲区//----------------------------small ram buffer start--------------------------- uint32_t pixel;uint8_t pdata[128];for(i = StartX; i <= EndX;){//every time read 32 pixelsk = bytesPerPixel * 32;res = f_read(pbmpfile, pdata, k, &bytesread);//err or no more dataif(FR_OK!=res || 0==bytesread){LCD_Set_WriteDir(LCDWriteDir_L2R_U2D);//restore display directionreturn;}//display 32 pixelsk = 0; pixel = 0;while(k < bytesread){//color - combine RGBif(32 == BitMapHeader.bminfoHeader.biBitCount){color = (pdata[k])>>3; //Bcolor += ((uint16_t)(pdata[k+1])<<3) & 0x07E0; //Gcolor += ((uint16_t)(pdata[k+2])<<8) & 0xF800; //R}else if(24 == BitMapHeader.bminfoHeader.biBitCount){color = (pdata[k])>>3; //Bcolor += ((uint16_t)(pdata[k+1])<<3) & 0x07E0; //Gcolor += ((uint16_t)(pdata[k+2])<<8) & 0xF800; //R}else if(0 == BitMapHeader.bminfoHeader.biCompression){//BI_RGB,RGB 555color = ((uint16_t)pdata[k] & 0x1F); //Rcolor += (((uint16_t)pdata[k]) & 0xE0)<<1; //Gcolor += ((uint16_t)pdata[k+1])<<9; //R,G}else{//RGB 565color = pdata[k]; //G,Bcolor += ((uint16_t)pdata[k+1])<<8; //R,G}//write LCDLCD_Write_Data(color);//Write 16-bit GRAM//next pixelk += bytesPerPixel;pixel++;//reach line endif(i + pixel > EndX) break;}//skip writed pixelsi += pixel;}//----------------------------small ram buffer end---------------------------- #endif}//end for(j)//restore display directionBSP_LCD_Set_WriteDir(LCDWriteDir_L2R_U2D);}-------------------------------------------------------------------------------By nicholasldf-------------------------------------------------------------------------------。

用c语言读取并显示bmp图像1

用c语言读取并显示bmp图像1

如何在WIN-TC中或TC++3.0中把一张BMP格式的图片显示出来?下面的是<<C & C++编程实例>>随书光盘上的代码,我在TC2.0下编译通过.它是利用了抖动技术显示了8bit和24bit的位图(也就是256色和16M色位图),应该能满足你的需要.不过,我想问下,你老师教过抖动显示吗?#include <stdio.h>#include <dos.h>#include <stdio.h>#include <conio.h>#define NoError 0#define ErrorFileOpen 1#define ErrorFileType 2#define ErrorImageColor 3typedef struct tagBITMAPFILEHEADER{unsigned int bfType;unsigned long bfSize;unsigned int bfReserved1;unsigned int bfReserved2;unsigned long bfoffBits;}BITMAPFILEHEADER;typedef struct tagBITMAPINFOHEADER{unsigned long biSize;unsigned long biWidth;unsigned long biHeight;unsigned int biPlanes;unsigned int biBitCount;unsigned long biCompression;unsigned long biSizeImage;unsigned long biXPelsPerMeter;unsigned long biYPelsPerMeter;unsigned long biClrUsed;unsigned long biClrImportant;} BITMAPINFOHEADER;typedef struct tagRGBQUAD{unsigned char rgbBlue;unsigned char rgbGreen;unsigned char rgbRed;unsigned char rgbReserved;} RGBQUAD;unsigned char PalReg[17]= { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0}; unsigned char StandardPal[48]= {0, 0, 0, 32, 0, 0, 0,32, 0, 32,32, 0, 0, 0,32, 32, 0,32, 0,32,32, 32,32, 32, 48, 48,48, 63, 0, 0, 0,63, 0, 63,63, 0, 0, 0,63, 63, 0,63, 0,63,63, 63,63,63, };unsigned char LightnessMatrix [16][16]= {{ 0,235,59,219,15,231,55,215,2,232,56,217,12,229,52,213},{128,64,187,123,143,79,183,119,130,66,184,120,140,76,180,116},{33,192,16,251,47,207,31,247,34,194,18,248,44,204,28,244},{161,97,144,80,175,111,159,95,162,98,146,82,172,108,156,92},{8,225,48,208,5,239,63,223,10,226,50,210,6,236,60,220},{136,72,176,112,133,69,191,127,138,74,178,114,134,70,188,124},{41,200,24,240,36,197,20,255,42,202,26,242,38,198,22,252},{169,105,152,88,164,100,148,84,170,106,154,90,166,102,150,86},{3,233,57,216,13,228,53,212,1,234,58,218,14,230,54,214},{131,67,185,121,141,77,181,117,129,65,186,122,142,78,182,118},{35,195,19,249,45,205,29,245,32,193,17,250,46,206,30,246},{163,99,147,83,173,109,157,93,160,96,145,81,174,110,158,94},{11,227,51,211,7,237,61,221,9,224,49,209,4,238,62,222},{139,75,179,115,135,71,189,125,137,73,177,113,132,68,190,126},{43,203,27,243,39,199,23,253,40,201,25,241,37,196,21,254},{171,107,155,91,167,103,151,87,168,104,153,89,165,101,149,85},};unsigned char ColorTable[2][2][2]= {{{0,12},{10,14}},{{9,13},{11,15}}}; unsigned char ColorMap[256][3];int ShowBmp(char *FileName);int GetColor(unsigned char R,unsigned char G, unsigned char B,int X,int Y); void SetVideoMode(unsigned char Mode);void SetPalReg(unsigned char *palReg);void SetDacReg(unsigned char *DacReg, int Color, int Count);void PutPixel(int X, int Y, unsigned char Color);/* 主函数*/void main (int argc, char *argv[]){if(argc!=2){printf("Usage:\tSHOW Filename.BMP\n");exit(1);}ShowBmp(argv[1]);}/* 根据图像文件名,读取图像内容并利用抖动技术进行显示*/ int ShowBmp(char *FileName){FILE *Fp;BITMAPFILEHEADER FileHead;BITMAPINFOHEADER InfoHead;RGBQUAD RGB;int N, W,Y,X,C,Color;unsigned char Buffer[4096];Fp=fopen(FileName,"rb");if (Fp==NULL)return(ErrorFileOpen);fread(&FileHead,sizeof(BITMAPFILEHEADER),1,Fp);if(FileHead.bfType!='BM'){fclose(Fp);return(ErrorFileType);}fread(&InfoHead,sizeof(BITMAPINFOHEADER),1,Fp);if(InfoHead.biBitCount!=8 && InfoHead.biBitCount!=24){fclose(Fp);return(ErrorImageColor);}/* 设置显示模式和显示区域*/SetVideoMode(0x12);SetPalReg(PalReg);SetDacReg(StandardPal,0,16);/* 对两种不同色彩数的图像分别进行处理*/if(InfoHead.biBitCount==8) /* 256色*/{for (N=0;N<256;N++){fread(&RGB, sizeof(RGBQUAD),1,Fp);ColorMap[N][0]=RGB.rgbRed;ColorMap[N][1]=RGB.rgbGreen;ColorMap[N][2]=RGB.rgbBlue;}W=(InfoHead.biWidth+3)/4*4;for(Y=InfoHead.biHeight-1;Y>=480;Y--)fread(Buffer,sizeof(unsigned char),W,Fp);for(;Y>0;Y--){fread(Buffer,sizeof(unsigned char),W,Fp);for (X=0;X<InfoHead.biWidth && X<640;X++){C=Buffer[X];Color=GetColor(ColorMap[C][0],ColorMap[C][1],ColorMap[C][2],X,Y); PutPixel (X,Y,Color);}}}else /* 24bits真彩色*/{W=(InfoHead.biWidth*3+3)/4*4;for(Y=InfoHead.biHeight-1;Y>639;Y--)fread(Buffer,sizeof(unsigned char),W,Fp);for(;Y>=0;Y--){fread(Buffer,sizeof(unsigned char),W,Fp);for(X=0;X<InfoHead.biWidth && X<640;X++){C=X*3;Color=GetColor(Buffer[C+2],Buffer[C+1],Buffer[C],X,Y);PutPixel(X,Y,Color);}}}getch();fclose(Fp);SetVideoMode(0x03);return(NoError);}int GetColor(unsigned char R, unsigned char G, unsigned char B, int X, int Y) {unsigned int L=LightnessMatrix[Y & 0x0F][X & 0x0F];return(ColorTable[(unsigned int)R*256/255>L][(unsigned int)G*256/255>L][(unsigned int)B*256/255>L]); }void SetVideoMode(unsigned char Mode){_AH=0x00;_AL=Mode;geninterrupt(0x10);}void SetPalReg(unsigned char *PalReg){_ES=FP_SEG((unsigned char far*)PalReg);_DX=FP_OFF((unsigned char far*)PalReg);_AX=0x1002;geninterrupt(0x10);}void SetDacReg(unsigned char *DacReg,int Color,int Count){_ES=FP_SEG((unsigned char far*)DacReg);_DX=FP_OFF((unsigned char far*)DacReg);_AX=0x1012;_BX=Color;_CX=Count;geninterrupt(0x10);}/* 在对应位置显示像素色彩*/void PutPixel(int X, int Y, unsigned char Color){_AH=0x0C;_AL=Color;_CX=X;_DX=Y;geninterrupt(0x10);}16色位图的显示文:吴进/Luckylai对于象大家常用TC的16色图形模式编程的初学者,如果能在程序里使用图片那就会方便很多了,以前在TC256上看见吴进写的《TC的16色BMP闪电显示(66k) 》的代码,发现写的的确不错,而且绝对能在TC的initgraph()初始化的BGI模式下使用。

实现bmp位图读取-显示-旋转的代码

实现bmp位图读取-显示-旋转的代码

实现bmp位图读取-显示-旋转的代码在视图类中定义以下两个方法:方法一:void RedFile();方法二:void RotateAnyAngle(HDC dcSrc,int SrcWidth,int SrcHeight,double angle,HDC hDC);代码的实现如下:void CTopView::RedFile(){/***************************读取信息********************************/LPCTSTR lpszFileName="f:\\b.bmp"; //文件路径CFile file; //用于读取BMP文件BITMAPFILEHEADER bfhHeader; //bmp文件头BITMAPINFOHEADER bmiHeader; //bmp格式头LPBITMAPINFO lpBitmapInfo; //bmp格式具体信息int bmpWidth=0; //图片宽度int bmpHeight = 0; //图片高度if(!file.Open(lpszFileName,CFile::modeRead))return ; //打开文件//读取文件头file.Read(&bfhHeader,sizeof(BITMAPFILEHEADER));if(bfhHeader.bfType!=((WORD) ('M'<<8)|'B')) //判断是否是"BM"return ;if(bfhHeader.bfSize!=file.GetLength())return ;//读取位图信息if (file.Read((LPSTR)&bmiHeader, sizeof(bmiHeader)) != sizeof(bmiHeader)) return ;bmpHeight = bmiHeader.biHeight; //得到高度和宽度bmpWidth = bmiHeader.biWidth;file.SeekToBegin(); //指针移动到文件的开头file.Read(&bfhHeader,sizeof(BITMAPFILEHEADER));UINT uBmpInfoLen=(UINT) bfhHeader.bfOffBits-sizeof(BITMAPFILEHEADER);//File SizelpBitmapInfo=(LPBITMAPINFO) new BYTE[uBmpInfoLen]; //具体信息分配内存file.Read((LPVOID) lpBitmapInfo,uBmpInfoLen);if((* (LPDWORD)(lpBitmapInfo))!=sizeof(BITMAPINFOHEADER))return ;DWORD dwBitlen=bfhHeader.bfSize - bfhHeader.bfOffBits;//图像数据的字节大小 LPVOID lpSrcBits=new BYTE[dwBitlen]; //将数据读入lpSrcBits数组file.ReadHuge(lpSrcBits,dwBitlen);file.Close(); //关闭文件/*****************************显示图片***********************************/CClientDC hDC(this);StretchDIBits(hDC,0,0,bmpWidth,bmpHeight,0,0,bmpWidth,bmpHeight,lpSrcBits,lpBitmapInfo,DIB_RGB_COLORS,SRCCOPY);/*************************将图片加入内存设备环境*************************************/HDC dcSrc;HBITMAP bitmap;dcSrc=CreateCompatibleDC(hDC);//得到一个内存设备环境bitmap = CreateCompatibleBitmap(hDC,bmpWidth,bmpHeight);SelectObject(dcSrc,bitmap);BitBlt(dcSrc,0,0,bmpWidth,bmpHeight,hDC,0,0,SRCCOPY);//这一步很重要/***********************************旋转*********************************************///调用旋转函数double angle = (45/180.0)*3.14159;//旋转45Degree,可为任意角度RotateAnyAngle(dcSrc,bmpWidth,bmpHeight,angle,hDC);}/*参数解释如下:///////////////////////////////////////////////////////////////////////////// HDC dcSrc:要旋转的位图的内存设备环境,就是第四步创建的int SrcWidth:要旋转位图的宽度int SrcHeight:要旋转位图的高度double angle:所要旋转的角度,以弧度为单位HDC pDC:第三步得到的当前屏幕设备环境void RotateBitmap(HDC dcSrc,int SrcWidth,int SrcHeight,double angle,HDC pDC);*/////////////////////////////////////////////////////////////////////////////// ////////////////////////void CTopView::RotateAnyAngle(HDC dcSrc,int SrcWidth,int SrcHeight,double angle,HDC hDC){double x1,x2,x3;double y1,y2,y3;double maxWidth,maxHeight,minWidth,minHeight;double srcX,srcY;double sinA,cosA;double DstWidth;double DstHeight;HDC dcDst;//旋转后的内存设备环境HBITMAP newBitmap;sinA = sin(angle);cosA = cos(angle);x1 = -SrcHeight * sinA;y1 = SrcHeight * cosA;x2 = SrcWidth * cosA - SrcHeight * sinA;y2 = SrcHeight * cosA + SrcWidth * sinA;x3 = SrcWidth * cosA;y3 = SrcWidth * sinA;minWidth = x3>(x1>x2?x2:x1)?(x1>x2?x2:x1):x3;minWidth = minWidth>0?0:minWidth;minHeight = y3>(y1>y2?y2:y1)?(y1>y2?y2:y1):y3;minHeight = minHeight>0?0:minHeight;maxWidth = x3>(x1>x2?x1:x2)?x3:(x1>x2?x1:x2);maxWidth = maxWidth>0?maxWidth:0;maxHeight = y3>(y1>y2?y1:y2)?y3:(y1>y2?y1:y2);maxHeight = maxHeight>0?maxHeight:0;DstWidth = maxWidth - minWidth;DstHeight = maxHeight - minHeight;dcDst = CreateCompatibleDC(dcSrc);newBitmap = CreateCompatibleBitmap(dcSrc,(int)DstWidth,(int)DstHeight); SelectObject(dcDst,newBitmap);for( int I = 0 ;I<DstHeight;I++){for(int J = 0 ;J< DstWidth;J++){srcX = (J + minWidth) * cosA + (I + minHeight) * sinA;srcY = (I + minHeight) * cosA - (J + minWidth) * sinA;if( (srcX >= 0) && (srcX <= SrcWidth) &&(srcY >= 0) && (srcY <= SrcHeight)) {BitBlt(dcDst, J, I, 1, 1, dcSrc,(int)srcX, (int)srcY, SRCCOPY);}}}//显示旋转后的位图BitBlt(hDC,150,10,(int)DstWidth,(int)DstHeight,dcDst,0,0,SRCCOPY);DeleteObject(newBitmap);DeleteDC(dcDst);。

bmp编码规则

bmp编码规则

BMP(Bitmap Image File)是一种位图图像文件格式,它的编码规则如下:
1. BMP文件格式由文件头、位图信息头、颜色表和位图数据四部分组成。

2. 文件头包括两个字节的文件类型标识和四个字节的文件大小。

其中,文件类型标识固定为0x4d42,即"BM"。

3. 位图信息头包括14个字节的信息,包括位图宽度、位图高度、像素位数、压缩方式等。

4. 颜色表用于存储位图中的颜色信息,它由若干个RGBQUAD结构组成。

每个RGBQUAD结构包含红色、绿色、蓝色和保留字段,其中保留字段用于填充位图数据中的空隙。

5. 位图数据是位图中每个像素值的序列,按照扫描行内从左到右、扫描行之间从下到上的顺序记录。

需要注意的是,BMP文件的编码方式有多种,包括不压缩、RLE压缩等。

不同的编码方式会影响到BMP文件的存储大小和显示效果。

1 怎样读取BMP文件中的像素数据与显示位图

1  怎样读取BMP文件中的像素数据与显示位图

怎样读取BMP位图的数据与显示位图计算机与信息工程系管庶安一 BMP位图文件的结构以24位BMP位图文件为例说明。

BMP位图文件结构如下表所示:位图数据◇逐行逐列记录各像素点的三基色分量。

◇每一像素点占用三个字节,分别表示蓝色分量B、绿色分量G、红色分量R的值。

◇ 设图像有n行、m列像素,行顺序为从下向上分别为第1行、第2行……;列顺序为从左向右分别为第1列、第2列……。

按此顺序将各像素的三基色值记录于BYTE型的一维数组中,如下图所示:注意:当一行占用的字节数不是4的整数倍时,应补充1~3个无效字节,使一行占用的字节数能被4整除。

无效字节可为任意值,不会影响图像内容。

二读取BMP位图数据(1)在MFC工程中的 .H文件中定义如下全局成员变量:BITMAPFILEHEADER FileHead; // 定义存放 .BMP 文件头的结构BITMAPINFOHEADER BmpInfo; // 定义存放 .BMP 信息头的结构LPBYTE lpImage; // 定义存放 .BMP文件中的位图数据的BYTE型指针typedef struct CCC{ // 定义能存放一个像素的3个基色值的结构类型BYTE B;BYTE G;BYTE R;};CCC C3 [480] [640];// 定义能存放一幅480行、640列像素的二维数组,以便图像处理与识别时运算(2)在.CPP文件中的类构造函数中,为lpImage指针申请内存:lpImage=(LPBYTE)new BYTE[640*480*3];在.CPP文件中的类析构函数中,为lpImage指针释放内存:delete[ ] lpImage;(3)在.CPP文件中的适当函数中打开.BMP文件,读取信息头和位图数据。

CFile f;BOOL OK;OK=f.Open( Bmp.PathName,CFile::modeRead|CFile::typeBinary|CFile::shareExcl usive,NULL);if(!OK) return(-1); //不能打开文件,返回失败标志-1f.Read(&FileHead,sizeof(FileHead)); //读文件头if(FileHead.bfType!=0x4d42) {f.Close();return -2; //不是BMP文件,返回失败标志-2 }short x,y,z;z=(BmpInfo.biWidth*3/4)*4+(BmpInfo.biWidth*3%4==0 ? 0 : 4);f.Read(&BmpInfo,sizeof(BmpInfo)); //读信息头f.Seek(FileHead.bfOffBits,0);f.Read(lpImage,BmpInfo.biHeight*z); //读全部位图数据f.Close();for(y=BmpInfo.biHeight-1;y>=0;y--){memcpy(C3[y],lpImage+(BmpInfo.biHeight-1-y)*z,z); //逐行将位图数据填写到C3数组中}return 1; //最后,返回成功标志1三显示位图1 先按上述方法读取位图数据,再将读取数据予以显示。

BMP格式介绍(一)

BMP格式介绍(一)

BMP格式介绍(⼀)原理篇:⼀、编码的意义。

让我们从⼀个简单的问题开始,-2&-255(中间的操作符表⽰and的意思)的结果是多少,这个很简单的问题,但是能够写出解答过程的⼈并不多。

这个看起来和图⽚格式没有关系的问题恰恰是图⽚格式的核⼼内容以⾄于整个计算机系统的核⼼内容,多媒体技术虽然没有数据结构,操作系统等计算机基础课所占的地位重,但是在于研究编码⽅⾯有着⾮常重要的地位。

图像其实可以看做⼀种特殊编码过的⽂件。

⼆、从简单的24位bmp开始bmp是最常见也是编码⽅式最简单的图⽚格式,这⾥不说明⼀幅图⽚是怎么显⽰在电脑上的,那不是多媒体技术研究的问题,我们来研究bmp的格式问题,为了使各位能够最快的了解bmp格式,我们从24位的⼀个16*16的⼩图像开始。

我们使⽤常⽤的绘图软件创建⼀个16*16的24位bmp图像,如下图所⽰:可以看到图⽚很⼩,我们使⽤ultra-edit看看其内部是什么(ultra-edit是⼀个⽐记事本更加⾼级的编辑软件,可以在⽹上下载到),我们打开其内部看到的是如下的⼀个⼗六进制的数据⽂件:看起来很⾼深⽽⼜很凌乱的样⼦,我们慢慢地说明这些看起来很凌乱的数据流都代表了什么意思,⾸先我们要说明的是,这⾥⾯⼀个数字代表的是⼀个字节,⽐如头两个数42 4d是两个⼗六进制的数,代表了两个字节。

可以看到在UE中⼀⾏是⼗六个字节。

在具体说明每个字节的含义之前,⾸先需要说明的是字节的排布⽅式,在操作系统和计算机组成结构⾥⾯有⼤端法和⼩端法(如果有遗忘可以查⼀下书),简易的说法是这样的,⼩端法的意思是“低地址村存放低位数据,⾼地址存放⾼位数据”,⼤端法就是反过来的,举个例⼦,如果地址从左到右依次增⼤,那么数据01 02的⼩端法存储⽅式是02 01,⼤端法的存储⽅式就是01 02。

在所有的intel的机器上都是采⽤的⼩端法,⽽⼤端法主要存在于摩托罗拉造的处理器的机器上,所以如果你⽤的是⼀个果粉,⽤的是MAC的话,那么你看到的数据排布⽅式是和我们说明中是相反的。

C++实现bmp格式图像读写

C++实现bmp格式图像读写

C++实现bmp格式图像读写bmp格式图像有⼀个特点就是这类数据被分为四个部分:1.位图⽂件头(Bitmap File Header) ,⼤⼩:14字节主要包括位图⽂件⼤⼩和位图⽂件类型信息2.位图信息头(Bitmap Info Header),⼤⼩:40字节主要包括:位图的宽度和⾼度,像素为单位、每个像素所占位数(1⿊⽩图像),(4-16⾊图)、(8-256⾊图)、(24-真彩⾊图),新的BMP格式可以⽀持32位⾊。

还有其它⽔平和垂直分辨⼒(单位:像素/⽶)等3.颜⾊表(Color Map),⼤⼩:4个字节三⼤类:蓝⾊分量、绿⾊分量、红⾊分量4.位图数据(Data Body)对于2⾊位图⽤1位就可以表⽰该像素,那么1个字节就可以储存8个像素的颜⾊值对于16⾊位图,⽤4个字节表⽰⼀个像素颜⾊,那么⼀个字节可以储存2个像素颜⾊值对于256⾊位图,1个字节刚好储存1个像素的颜⾊值对于真彩⾊位图,则需要3个字节才能表⽰⼀个像素的颜⾊值1.读bmp图像bool readBmp(char *bmpName){//⼆进制读⽅式打开指定的图像⽂件FILE *fp=fopen(bmpName,"rb");if(fp==0) return 0;//跳过位图⽂件头结构BITMAPFILEHEADERfseek(fp, sizeof(BITMAPFILEHEADER),0);//定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中BITMAPINFOHEADER head;fread(&head, sizeof(BITMAPINFOHEADER), 1,fp);//获取图像宽、⾼、每像素所占位数等信息bmpWidth = head.biWidth;bmpHeight = head.biHeight;biBitCount = head.biBitCount;//定义变量,计算图像每⾏像素所占的字节数(必须是4的倍数)int lineByte=(bmpWidth * biBitCount/8+3)/4*4;//灰度图像有颜⾊表,且颜⾊表表项为256if(biBitCount==8){//申请颜⾊表所需要的空间,读颜⾊表进内存pColorTable=new RGBQUAD[256];fread(pColorTable,sizeof(RGBQUAD),256,fp);}//申请位图数据所需要的空间,读位图数据进内存pBmpBuf=new unsigned char[lineByte * bmpHeight];fread(pBmpBuf,1,lineByte * bmpHeight,fp);//关闭⽂件fclose(fp);return 1;}2.写bmp图像bool saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height,int biBitCount, RGBQUAD *pColorTable){//如果位图数据指针为0,则没有数据传⼊,函数返回if(!imgBuf)return 0;//颜⾊表⼤⼩,以字节为单位,灰度图像颜⾊表为1024字节,彩⾊图像颜⾊表⼤⼩为0int colorTablesize=0;if(biBitCount==8)colorTablesize=1024;//待存储图像数据每⾏字节数为4的倍数int lineByte=(width * biBitCount/8+3)/4*4;//以⼆进制写的⽅式打开⽂件FILE *fp=fopen(bmpName,"wb");if(fp==0) return 0;//申请位图⽂件头结构变量,填写⽂件头信息BITMAPFILEHEADER fileHead;fileHead.bfType = 0x4D42;//bmp类型//bfSize是图像⽂件4个组成部分之和fileHead.bfSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+ colorTablesize + lineByte*height;fileHead.bfReserved1 = 0;fileHead.bfReserved2 = 0;//bfOffBits是图像⽂件前三个部分所需空间之和fileHead.bfOffBits=54+colorTablesize;//写⽂件头进⽂件fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp);//申请位图信息头结构变量,填写信息头信息BITMAPINFOHEADER head;head.biBitCount=biBitCount;head.biClrImportant=0;head.biClrUsed=0;head.biCompression=0;head.biHeight=height;head.biPlanes=1;head.biSize=40;head.biSizeImage=lineByte*height;head.biWidth=width;head.biXPelsPerMeter=0;head.biYPelsPerMeter=0;//写位图信息头进内存fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp);//如果灰度图像,有颜⾊表,写⼊⽂件if(biBitCount==8)fwrite(pColorTable, sizeof(RGBQUAD),256, fp);//写位图数据进⽂件fwrite(imgBuf, height*lineByte, 1, fp);//关闭⽂件fclose(fp);return 1;}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

用普通方法显示BMP位图,占内存大,速度慢,在图形缩小时,失真严重,在低颜色位数的设备上显示高颜色位数的图形图形时失真大。

本文采用视频函数显示BMP位图,可以消除以上的缺点。

---- 一、BMP文件结构---- 1. BMP文件组成---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。

---- 2. BMP文件头---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。

---- 其结构定义如下:typedef struct tagBITMAPFILEHEADER{WORDbfType; // 位图文件的类型,必须为BMDWORD bfSize; // 位图文件的大小,以字节为单位WORDbfReserved1; // 位图文件保留字,必须为0WORDbfReserved2; // 位图文件保留字,必须为0DWORD bfOffBits; // 位图数据的起始位置,以相对于位图// 文件头的偏移量表示,以字节为单位} BITMAPFILEHEADER;---- 3. 位图信息头----BMP位图信息头数据用于说明位图的尺寸等信息。

typedef struct tagBITMAPINFOHEADER{DWORD biSize; // 本结构所占用字节数LONGbiWidth; // 位图的宽度,以像素为单位LONGbiHeight; // 位图的高度,以像素为单位WORD biPlanes; // 目标设备的级别,必须为1WORD biBitCount// 每个像素所需的位数,必须是1(双色),// 4(16色),8(256色)或24(真彩色)之一DWORD biCompression; // 位图压缩类型,必须是0(不压缩),// 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一DWORD biSizeImage; // 位图的大小,以字节为单位LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数DWORD biClrImportant;// 位图显示过程中重要的颜色数} BITMAPINFOHEADER;---- 4. 颜色表---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。

RGBQUAD结构的定义如下:typedef struct tagRGBQUAD {BYTErgbBlue;// 蓝色的亮度(值范围为0-255)BYTErgbGreen; // 绿色的亮度(值范围为0-255)BYTErgbRed; // 红色的亮度(值范围为0-255)BYTErgbReserved;// 保留,必须为0} RGBQUAD;颜色表中RGBQUAD结构数据的个数有biBitCount来确定:当biBitCount=1,4,8时,分别有2,16,256个表项;当biBitCount=24时,没有颜色表项。

位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:typedef struct tagBITMAPINFO {BITMAPINFOHEADER bmiHeader; // 位图信息头RGBQUAD bmiColors[1]; // 颜色表} BITMAPINFO;---- 5. 位图数据---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。

位图的一个像素值所占的字节数:当biBitCount=1时,8个像素占1个字节;当biBitCount=4时,2个像素占1个字节;当biBitCount=8时,1个像素占1个字节;当biBitCount=24时,1个像素占3个字节;Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充,一个扫描行所占的字节数计算方法:DataSizePerLine= (biWidth* biBitCount+31)/8;// 一个扫描行所占的字节数DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数位图数据的大小(不压缩情况下):DataSize= DataSizePerLine* biHeight;---- 二、BMP位图一般显示方法---- 1. 申请内存空间用于存放位图文件---- GlobalAlloc(GHND,FileLength);---- 2. 位图文件读入所申请内存空间中---- LoadFileToMemory( mpBitsSrc,mFileName);---- 3. 在OnPaint等函数中用创建显示用位图---- 用CreateDIBitmap()创建显示用位图,用CreateCompatibleDC()创建兼容DC,---- 用SelectBitmap()选择显示位图。

---- 4. 用BitBlt或StretchBlt等函数显示位图---- 5. 用DeleteObject()删除所创建的位图---- 以上方法的缺点是: 1)显示速度慢; 2) 内存占用大; 3) 位图在缩小显示时图形失真大,(可通过安装字体平滑软件来解决); 4) 在低颜色位数的设备上(如256显示模式)显示高颜色位数的图形(如真彩色)图形失真严重。

---- 三、BMP位图缩放显示---- 用DrawDib视频函数来显示位图,内存占用少,速度快,而且还可以对图形进行淡化(Dithering)处理。

淡化处理是一种图形算法,可以用来在一个支持比图像所用颜色要少的设备上显示彩色图像。

BMP位图显示方法如下:---- 1. 打开视频函数DrawDibOpen(),一般放在在构造函数中---- 2. 申请内存空间用于存放位图文件---- GlobalAlloc(GHND,FileLength);---- 3. 位图文件读入所申请内存空间中---- LoadFileToMemory( mpBitsSrc,mFileName);---- 4. 在OnPaint等函数中用DrawDibRealize(),DrawDibDraw()显示位图---- 5. 关闭视频函数DrawDibClose(),一般放在在析构函数中---- 以上方法的优点是: 1)显示速度快; 2) 内存占用少; 3) 缩放显示时图形失真小,4) 在低颜色位数的设备上显示高颜色位数的图形图形时失真小; 5) 通过直接处理位图数据,可以制作简单动画。

---- 四、CViewBimap类编程要点---- 1. 在CViewBimap类中添加视频函数等成员HDRAWDIB m_hDrawDib; // 视频函数HANDLEmhBitsSrc; // 位图文件句柄(内存)LPSTR mpBitsSrc; // 位图文件地址(内存) BITMAPINFOHEADER *mpBitmapInfo; // 位图信息头---- 2. 在CViewBimap类构造函数中添加打开视频函数---- m_hDrawDib= DrawDibOpen();---- 3. 在CViewBimap类析构函数中添加关闭视频函数if( m_hDrawDib != NULL){DrawDibClose( m_hDrawDib);m_hDrawDib = NULL;}---- 4. 在CViewBimap类图形显示函数OnPaint中添加GraphicDraw() voidCViewBitmap::OnPaint(){CPaintDC dc(this); // device context for painting GraphicDraw( );}voidCViewBitmap::GraphicDraw( void ){CClientDC dc(this); // device context for painting BITMAPFILEHEADER *pBitmapFileHeader;ULONG bfoffBits= 0;CPoint Wid;// 图形文件名有效(=0 BMP)if( mBitmapFileType < ID_BITMAP_BMP ) return;// 图形文件名有效(=0 BMP)// 准备显示真彩位图pBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc; bfoffBits= pBitmapFileHeader-> bfOffBits;// 使用普通函数显示位图if( m_hDrawDib == NULL || mDispMethod == 0){HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC,mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits,(LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS);// 建立位图HDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立内存HBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap); // 选择对象// 成员CRect mDispR用于指示图形显示区域的大小.// 成员CPoint mPos用于指示图形显示起始位置坐标.if( mPos.x > (mpBitmapInfo- > biWidth - mDispR.Width() )) mPos.x= mpBitmapInfo-> biWidth - mDispR.Width() ;if( mPos.y > (mpBitmapInfo- > biHeight- mDispR.Height())) mPos.y= mpBitmapInfo- > biHeight- mDispR.Height();if( mPos.x < 0 ) mPos.x= 0;if( mPos.y < 0 ) mPos.y= 0;if( mFullViewTog == 0){// 显示真彩位图::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),hMemDC,mPos.x,mPos.y, SRCCOPY);} else {::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),hMemDC,0,0, mpBitmapInfo- > biWidth, mpBitmapInfo-> biHeight, SRCCOPY);}// 结束显示真彩位图::DeleteObject(SelectObject(hMemDC,hBitmapOld));// 删除位图} else {// 使用视频函数显示位图if( mPos.x > (mpBitmapInfo- > biWidth - mDispR.Width() )) mPos.x= mpBitmapInfo- > biWidth - mDispR.Width() ;if( mPos.y > (mpBitmapInfo- > biHeight- mDispR.Height())) mPos.y= mpBitmapInfo- > biHeight- mDispR.Height();if( mPos.x < 0 ) mPos.x= 0;if( mPos.y < 0 ) mPos.y= 0;// 显示真彩位图DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE);if( mFullViewTog == 0){Wid.x= mDispR.Width();Wid.y= mDispR.Height();// 1:1 显示时, 不能大于图形大小if( Wid.x > mpBitmapInfo- > biWidth )Wid.x = mpBitmapInfo- > biWidth;if( Wid.y > mpBitmapInfo- > biHeight)Wid.y = mpBitmapInfo- > biHeight;DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(), 0, 0, Wid.x, Wid.y,mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),mPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL);} else {DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(),0, 0, mDispR.Width(), mDispR.Height(),mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),0, 0, mpBitmapInfo- > biWidth, mpBitmapInfo- > biHeight,DDF_BACKGROUNDPAL);}}return;}---- 五、使用CViewBimap类显示BMP位图---- 1. 在Visual C++5.0中新建一个名称为mymap工程文件,类型为MFC AppWizard[exe]。

相关文档
最新文档