C语言 BMP图片处理

合集下载

C语言实现BMP图片生成

C语言实现BMP图片生成

C语⾔实现BMP图⽚⽣成###include <stdio.h>#include <stdlib.h>#include <string.h>typedef unsigned char byte;typedef unsigned short dbyte;typedef unsigned long int dword;typedef unsigned short word;/********************************************定义bmp⽂件的头部数据结构********************************************/#pragma pack(push,2) //保持2字节对齐struct tagBITMAPFILEHEADER {//bmp file headerdbyte bfType; //⽂件类型dword bfSize; //⽂件⼤⼩,字节为单位word bfReserved1; //保留,必须为0word bfReserved2; //保留,必须为0dword bfOffBits; //从⽂件头开始的偏移量//bmp info headdword biSize; //该结构的⼤⼩dword biWidth; //图像的宽度,以像素为单位dword biHeight; //图像的⾼度,以像素为单位word biPlanes; //为⽬标设备说明位⾯数,其值总是设为1word biBitCount; //说明⽐特数/像素dword biCompression; //图像数据压缩类型dword biSizeImage; //图像⼤⼩,以字节为单位dword biXPelsPerMeter; //⽔平分辨率,像素/⽶dword biYPelsPerMeter; //垂直分辨率,同上dword biClrUsed; //位图实际使⽤的彩⾊表中的颜⾊索引数dword biClrImportant; //对图像显⽰有重要影响的颜⾊索引的数⽬//bmp rgb quad//对于16位,24位,32位的位图不需要⾊彩表//unsigned char rgbBlue; //指定蓝⾊强度//unsigned char rgbGreen; //指定绿⾊强度//unsigned char rgbRed; //指定红⾊强度//unsigned char rgbReserved; //保留,设置为0}BMPFILEHEADER;#pragma (pop)struct tagBITMAPFILEHEADER *bmp_p; //定义bmp⽂件头结构体指针FILE *fd; //定义⼀个⽂件类型的指针/**************************************************************初始化bmp⽂件头部,设置bmp图⽚**************************************************************/void Init_bmp_head(void){bmp_p = &BMPFILEHEADER;bmp_p-> bfType = 0x4D42; //⽂件类型bmp_p-> bfSize = 0x25836; //⽂件⼤⼩,字节为单位bmp_p-> bfReserved1 = 0x0; //保留,必须为0bmp_p-> bfReserved2 = 0x0; //保留,必须为0bmp_p-> bfOffBits = 0x36; //从⽂件头开始的偏移量//bmp info headbmp_p-> biSize = 0x28; //该结构的⼤⼩bmp_p-> biWidth = 320; //图像的宽度,以像素为单位bmp_p-> biHeight = 240; //图像的⾼度,以像素为单位bmp_p-> biPlanes = 0x01; //为⽬标设备说明位⾯数,其值总是设为1bmp_p-> biBitCount = 16; //说明⽐特数/像素bmp_p-> biCompression = 0; //图像数据压缩类型bmp_p-> biSizeImage = 0x25800;//0x09f8; //图像⼤⼩,以字节为单位bmp_p-> biXPelsPerMeter = 0x60;//0x60; //⽔平分辨率,像素/⽶bmp_p-> biYPelsPerMeter = 0x60; //垂直分辨率,同上bmp_p-> biClrUsed = 0; //位图实际使⽤的彩⾊表中的颜⾊索引数bmp_p-> biClrImportant = 0; //对图像显⽰有重要影响的颜⾊索引的数⽬}int main(void){static char *file_name =NULL; //保存⽂件名的指针static long file_length = 0x25836; //⽂件的⼤⼩(整个⽂件)unsigned char *file_p = NULL; //写⼊数据指针unsigned char *file_p_tmp = NULL; //写⼊数据临时指针unsigned char *byte_copy_p = NULL; //⽂件头部传递指针unsigned char byte_copy = 0; //⽂件头部数据拷贝变量int i = 0;file_name = "test1.bmp";Init_bmp_head();file_p = (unsigned char *)malloc(sizeof(char)*153654); //申请⼀段内存 file_p_tmp = file_p;for(i = 0;i < 153654;i++ ){if(i%2 ==0){*file_p_tmp = 0x00; //图像前8位值}else{*file_p_tmp = 0xf0; //图像后8位值}file_p_tmp++;}byte_copy_p = (unsigned char *)bmp_p;file_p_tmp = file_p;for(i = 0;i < 54;i++){*file_p_tmp = *byte_copy_p;file_p_tmp++;byte_copy_p++;}fd = fopen(file_name, "w");fwrite(file_p, file_length, 1,fd);free(file_p); //释放申请的内存(重要)fclose(fd);printf("Done success\n");getchar();return (0);}。

用VC编程实现BMP图像裁切

用VC编程实现BMP图像裁切

5.5 用VC编程实现BMP图像裁切随着计算电子技术和计算机技术的发展,数字图像处理进入高速发展时期,许多成熟的图像处理软件如雨后春笋般层出不穷。

在大多数图像处理软件中都有图像裁切功能,用它能够快速提取感兴趣区域,去掉多余的图像内容。

那么怎样编程实现图像裁切呢,下面以BMP图像为例介绍一下如何用VC实现图像裁切。

先介绍第一种方法,将图像数据全部读入内存,然后将感兴趣区域裁切下来。

在许多数字图像处理的书中都有关于BMP图像存储结构的章节,这里就不再详细介绍了。

BMP文件一般分为四个部分:位图头文件、位图信息头、调色板和图像数据。

图像裁切要用到位图信息头中的几个参数值:biWidth(图像宽度)、biHeight(图像高度)、biBitCount(每个像素的位数)、biSizeImage(图像长度)。

图像裁切首先要确定裁切区域内每个像素在整幅图像中的位置,我们以裁切区域中心点像素位置起算,要注意的是图像数据的存储是从最下面一行的左边开始的。

如下图,Height是图像高,Width是图像宽,ctPoint是裁切区域中心点坐标,dwX和dwY分别是裁切区域的宽和高。

以256色图像为例(每个像素占一个字节),裁切区域左下角像素(也就是裁切后图像的第一个像素)位置为(Height-ctPoint.y-dwY/2-1)×Width+ctPoint.x-dwX/2,左下角像素位置确定了,裁切区域内的其他像素位置就很容易确定。

确定了裁切区域内每个像素的位置后,就可以把这些像素的值赋给裁切后图像的相应像素。

裁切后图像的位图信息头和调色板只要从原图像数据中拷贝就可以了,修改信息头中图像宽、高和长度值为裁切后的值。

按照上面的思路笔者用VC++ 6.0编写了一个图像裁切函数ClipDIB(),该函数首先计算裁切区域图像数据的大小,为裁切后的图像分配内存,然后将原图像的信息头、调色板拷贝给裁切后的图像,最后将原图像中裁切区域内的像素值赋给裁切后影像。

256级灰度BMP文件读写的源代码+c语言图像处理

256级灰度BMP文件读写的源代码+c语言图像处理

本文档最早发布于 /u/14951820541.256级灰度BMP文件读写的源代码!首先要明白256级灰度BMP文件的格式1.首先是一个14个字节的文件头,定义如下typedef struct tagBITMAPFILEHEADER{WORD bfType;DWORD bfSize;WORD bfReserved1;WORD bfReserved2;DWORD bfOffBits;} BITMAPFILEHEADER, *PBITMAPFILEHEADER;bfType是表明BMP文件类型的数据,在这里我们填入的是0x4d42,其实就是BM两个字,bfSize是文件大小,bfOffBits是文件头到数据块的偏移量,对于256级灰度图,就是1078个字节,后面会做描述2.接下来是40个字节的是描述位图属性的40个字节typedef struct tagBITMAPINFOHEADER{DWORD biSize;LONG biWidth;LONG biHeight;WORD biPlanes;WORD biBitCount;DWORD biCompression;DWORD biSizeImage;LONG biXPelsPerMeter;LONG biYPelsPerMeter;DWORD biClrUsed;DWORD biClrImportant;} BITMAPINFOHEADER, *PBITMAPINFOHEADER;这里面只有biWidth表示宽度,biPlanes表示高度,biBitCount对于256级灰度正好是83.由于是256级灰度图,那么有256个调色板数据,每个调色板是如下定义的typedef struct tagRGBQUAD {BYTE rgbBlue;BYTE rgbGreen;BYTE rgbRed;BYTE rgbReserved;}RGBQUAD, *PRGBQUAD;调色板数据其实告诉了显示器实际显示的时候的具体颜色,所以调色板长度是1024字节4.最后是按行组织的图像数据,但这些数据并不是简单的按照图像的高度宽度w*h的数组数据这些数据最重要的特点是a.按行组织,每行宽度是w,但是要进行4个字节的对齐。

完整程序_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;}。

用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模式下使用。

c语言image用法

c语言image用法

C语言image用法C语言是一种被广泛应用于系统编程和开发嵌入式软件的高级编程语言。

它提供了强大的图像处理功能,可以通过使用Image库来实现图像的加载、处理和保存。

本文将详细介绍C语言中Image库的用法。

一、Image库概述Image库是C语言中的一个常用工具库,它提供了一组函数和数据结构,用于处理图像数据。

使用Image库可以方便地读取、修改和保存图像,以实现各种图像处理操作。

常见的操作包括图像的缩放、旋转、灰度处理等。

二、图像的加载与保存在使用Image库进行图像处理之前,我们首先需要了解如何加载和保存图像。

Image库支持多种图像格式,包括常见的BMP、PNG、JPEG等。

1. 图像加载Image库提供了一个函数来加载图像数据,该函数的原型如下:IMAGE *imgLoad(const char *filename);该函数接收一个存储图像文件名的字符串作为参数,并返回一个指向图像结构体IMAGE的指针。

通过该指针,我们可以访问图像的宽度、高度和像素数据等信息。

2. 图像保存Image库同样提供了一个函数用于保存图像,函数原型如下:int imgSave(IMAGE *img, const char *filename);该函数接收一个指向IMAGE结构体的指针和一个存储图像文件名的字符串作为参数。

函数会将图像数据保存到指定的文件中,并返回保存是否成功的标志。

三、图像处理操作示例下面我们将通过几个示例演示Image库的图像处理操作。

假设我们有一张名为"image.bmp"的BMP格式图像,我们将使用Image库对该图像进行操作。

1. 图像缩放图像缩放是一种常见的图像处理操作,我们可以使用Image库的函数来实现图像的缩放。

以下是一个图像缩放的示例:#include <stdio.h>#include <image.h>int main() {IMAGE *img = imgLoad("image.bmp"); // 加载图像IMAGE *newImg = imgScale(img, 0.5, 0.5); // 缩小图像imgSave(newImg, "scaled_image.bmp"); // 保存缩放后的图像imgFree(img); // 释放内存imgFree(newImg);return 0;}在上述示例中,我们使用了imgScale函数实现了图像的缩放,该函数接收一个指向原始图像的指针和缩放比例作为参数。

BMP图像分割C语言程序

BMP图像分割C语言程序

} fseek(fp1,sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),S EEK_SET); fseek(fp2,sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER),S EEK_SET); for(i=0;i<255;i++) { fread(&pal[i].rgbBlue,1,1,fp1); fread(&pal[i].rgbGreen,1,1,fp1); fread(&pal[i].rgbRed,1,1,fp1); pal[i].rgbReserved=0; } line_bytes1=(biWidth1*biBitCount1+31)/32*4; line_bytes2=(biWidth2*biBitCount2+31)/32*4; pixel1=(BYTE*)malloc(biHeight1*line_bytes1*sizeof(BYTE)); memset(pixel1,0,biHeight1*line_bytes1*sizeof(BYTE)); if(pixel1==0) { printf("Fail to allocate memory to File one.\n"); fclose(fp1); fclose(fp2); return 1; } pixel2=(BYTE*)malloc(biHeight2*line_bytes2*sizeof(BYTE)); memset(pixel2,0,biHeight2*line_bytes2*sizeof(BYTE)); if(pixel2==0) { printf("Fail to allocate memory to File two.\n"); fclose(fp1); fclose(fp2); return 1; }

详解用VC实现bmp位图的打开-fengqing888的日志-网易博客

详解用VC实现bmp位图的打开-fengqing888的日志-网易博客

详解用VC实现bmp位图的打开-fengqing888的日志-网易博客详解用VC实现bmp位图的打开技术_图片编程 2009-12-18 13:59:17 阅读262 评论0 字号:大中小我最近在学VC++数字图像处理,作为一个初学者,万里长征的第一步当然是打开一幅图像,这几天一直在看怎么实现这一功能,虽说简单,但是如果这一步不能做到,那么下面也就无法进行了,所以我总结了一下这个过程,写出来供大家参考。

也希望大家多多批评啊。

这里我就不想介绍关于位图的理论内容了,只是写一下实现的部分。

0.准备工作创建一个SDI,工程名Test,“隐藏工具栏”和“打印和打印预览”取消了,不用那么复杂,简单点就行1.创建菜单创建两个菜单:Caption: 打开 ID: ID_FILE_OPENCaption: 显示原图 ID: IDM_YUANTU2.对打开菜单进行响应右键打开菜单,建立类向导,在CTestDoc类中,进行COMMAND响应,生成OnFileOpen函数,代码如下:void CTestDoc::OnFileOpen(){// TODO: Add your command handler code hereCFileDialog fileDlg(TRUE);//创建一个CfileDialog类对象fileDlg,第一个参数TRUE为打开对话框,若为FALSE,则为另存为fileDlg.m_ofn.lpstrTitle="图片打开对话框";//设置打开对话框的标题fileDlg.m_ofn.lpstrFilter="BMP Files(*.bmp)\0*.bmp\0\0";//设置打开的文件类型if(IDOK==fileDlg.DoModal ())//这个语句有两层意义,第一是dlg.DoModal()作用是弹出CPortDlg对话框,第二层是dlg.DoModal()==IDOK是你点击了对话框上的OK按钮就是说你同时做了上述两件事时就执行if语句后面的程序。

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

C语言BMP图片处理BMP是bitmap的缩写形式,bitmap顾名思义,就是位图也即Windows位图。

它一般由4部分组成:文件头信息块、图像描述信息块、颜色表(在真彩色模式无颜色表)和图像数据区组成。

在系统中以BMP为扩展名保存。

打开Windows的画图程序,在保存图像时,可以看到三个选项:2色位图(黑白)、16色位图、256色位图和24位位图。

这是最普通的生成位图的工具,在这里讲解的BMP位图形式,主要就是指用画图生成的位图(当然,也可以用其它工具软件生成)。

现在讲解BMP的4个组成部分:1.文件头信息块0000-0001:文件标识,为字母ASCII码“BM”。

0002-0005:文件大小。

0006-0009:保留,每字节以“00”填写。

000A-000D:记录图像数据区的起始位置。

各字节的信息依次含义为:文件头信息块大小,图像描述信息块的大小,图像颜色表的大小,保留(为01)。

2.图像描述信息块000E-0011:图像描述信息块的大小,常为28H。

0012-0015:图像宽度。

0016-0019:图像高度。

001A-001B:图像的plane(平面?)总数(恒为1)。

001C-001D:记录像素的位数,很重要的数值,图像的颜色数由该值决定。

001E-0021:数据压缩方式(数值位0:不压缩;1:8位压缩;2:4位压缩)。

0022-0025:图像区数据的大小。

0026-0029:水平每米有多少像素,在设备无关位图(.DIB)中,每字节以00H 填写。

002A-002D:垂直每米有多少像素,在设备无关位图(.DIB)中,每字节以00H 填写。

002E-0031:此图像所用的颜色数,如值为0,表示所有颜色一样重要。

3.颜色表颜色表的大小根据所使用的颜色模式而定:2色图像为8字节;16色图像位64字节;256色图像为1024字节。

其中,每4字节表示一种颜色,并以B(蓝色)、G(绿色)、R(红色)、alpha(像素的透明度值,一般不需要)。

即首先4字节表示颜色号0的颜色,接下来表示颜色号1的颜色,依此类推。

4.图像数据区颜色表接下来位为位图文件的图像数据区,在此部分记录着每点像素对应的颜色号,其记录方式也随颜色模式而定,既2色图像每点占1位(8位为1字节);16色图像每点占4位(半字节);256色图像每点占8位(1字节);真彩色图像每点占24位(3字节)。

所以,整个数据区的大小也会随之变化。

究其规律而言,可的出如下计算公式:图像数据信息大小=(图像宽度*图像高度*记录像素的位数)/8。

然而,未压缩的图像信息区的大小。

除了真彩色模式外,其余的均大于或等于数据信息的大小。

这是为什么呢?原因有两个:1.BMP文件记录一行图像是以字节为单位的。

因此,就不存在一个字节中的数据位信息表示的点在不同的两行中。

也就是说,设显示模式位16色,在每个字节分配两个点信息时,如果图像的宽度位奇数,那么最后一个像素点的信息将独占一个字节,这个字节的后4位将没有意义。

接下来的一个字节将开始记录下一行的信息。

2.为了显示的方便,除了真彩色外,其他的每中颜色模式的行字节数要用数据“00”补齐为4的整数倍。

如果显示模式为16色,当图像宽为19时,存储时每行则要补充4-(19/2+1)%4=2个字节(加1是因为里面有一个像素点要独占了一字节)。

如果显示模式为256色,当图像宽为19时,每行也要补充4-19%4=1个字节。

还有一点我要申明,当屏幕初始化为16或256色模式时,一定要设置调色板或修正颜色值,否则无法得到正确的图像颜色。

C代码//ReadBitMap//#include <string.h>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define WIDTHBYTES(bits) (((bits)+31)/32*4)typedef unsigned char BYTE;typedef unsigned short WORD;typedef unsigned long DWORD;typedef long LONG;//位图文件头信息结构定义//其中不包含文件类型信息(由于结构体的内存结构决定,要是加了的话将不能正确读取文件信息)typedef struct tagBITMAPFILEHEADER {DWORD bfSize; //文件大小WORD bfReserved1; //保留字,不考虑WORD bfReserved2; //保留字,同上DWORD bfOffBits; //实际位图数据的偏移字节数,即前三个部分长度之和} BITMAPFILEHEADER;//信息头BITMAPINFOHEADER,也是一个结构,其定义如下:typedef struct tagBITMAPINFOHEADER{//public:DWORD biSize; //指定此结构体的长度,为40LONG biWidth; //位图宽LONG biHeight; //位图高WORD biPlanes; //平面数,为1WORD biBitCount; //采用颜色位数,可以是1,2,4,8,16,24,新的可以是32DWORD biCompression; //压缩方式,可以是0,1,2,其中0表示不压缩DWORD biSizeImage; //实际位图数据占用的字节数LONG biXPelsPerMeter; //X方向分辨率LONG biYPelsPerMeter; //Y方向分辨率DWORD biClrUsed; //使用的颜色数,如果为0,则表示默认值(2^颜色位数) DWORD biClrImportant; //重要颜色数,如果为0,则表示所有颜色都是重要的} BITMAPINFOHEADER;//调色板Palette,当然,这里是对那些需要调色板的位图文件而言的。

24位和32位是不需要调色板的。

//(似乎是调色板结构体个数等于使用的颜色数。

)typedef struct tagRGBQUAD {//public:BYTE rgbBlue; //该颜色的蓝色分量BYTE rgbGreen; //该颜色的绿色分量BYTE rgbRed; //该颜色的红色分量BYTE rgbReserved; //保留值} RGBQUAD;void showBmpHead(BITMAPFILEHEADER* pBmpHead)printf("位图文件头:\n");printf("文件大小:%d\n",pBmpHead->bfSize);printf("保留字:%d\n",pBmpHead->bfReserved1);printf("保留字:%d\n",pBmpHead->bfReserved2);printf("实际位图数据的偏移字节数:%d\n",pBmpHead->bfOffBits);}void showBmpInforHead(tagBITMAPINFOHEADER* pBmpInforHead){printf("位图信息头:\n");printf("结构体的长度:%d\n",pBmpInforHead->biSize);printf("位图宽:%d\n",pBmpInforHead->biWidth);printf("位图高:%d\n",pBmpInforHead->biHeight);printf("biPlanes平面数:%d\n",pBmpInforHead->biPlanes);printf("biBitCount采用颜色位数:%d\n",pBmpInforHead->biBitCount);printf("压缩方式:%d\n",pBmpInforHead->biCompression);printf("biSizeImage实际位图数据占用的字节数:%d\n",pBmpInforHead->biSizeImage);printf("X方向分辨率:%d\n",pBmpInforHead->biXPelsPerMeter);printf("Y方向分辨率:%d\n",pBmpInforHead->biYPelsPerMeter);printf("使用的颜色数:%d\n",pBmpInforHead->biClrUsed);printf("重要颜色数:%d\n",pBmpInforHead->biClrImportant);}void showRgbQuan(tagRGBQUAD* pRGB){printf("(%-3d,%-3d,%-3d) ",pRGB->rgbRed,pRGB->rgbGreen,pRGB->rgbBlue); }void main(){BITMAPFILEHEADER bitHead;BITMAPINFOHEADER bitInfoHead;FILE* pfile;char strFile[50];printf("please input the .bmp file name:\n");scanf("%s",strFile);pfile = fopen(strFile,"rb");//打开文件if(pfile!=NULL){printf("file bkwood.bmp open success.\n");//读取位图文件头信息WORD fileType;fread(&fileType,1,sizeof(WORD),pfile);if(fileType != 0x4d42){printf("file is not .bmp file!");return;}//fseek(pfile,2,SEEK_CUR); // "BM"fread(&bitHead,1,sizeof(tagBITMAPFILEHEADER),pfile);showBmpHead(&bitHead);printf("\n\n");//读取位图信息头信息fread(&bitInfoHead,1,sizeof(BITMAPINFOHEADER),pfile); showBmpInforHead(&bitInfoHead);printf("\n");}else{printf("file open fail!\n");return;}tagRGBQUAD *pRgb ;if(bitInfoHead.biBitCount < 24)//有调色板{//读取调色盘结信息long nPlantNum = long(pow(2,double(bitInfoHead.biBitCount))); // Mix color Plant Number;pRgb=(tagRGBQUAD *)malloc(nPlantNum*sizeof(tagRGBQUAD));memset(pRgb,0,nPlantNum*sizeof(tagRGBQUAD));int num = fread(pRgb,4,nPlantNum,pfile);printf("Color Plate Number: %d\n",nPlantNum);printf("颜色板信息:\n");for (int i =0; i<nPlantNum;i++){if (i%5==0){printf("\n");}showRgbQuan(&pRgb[i]);}printf("\n");}int width = bitInfoHead.biWidth;int height = bitInfoHead.biHeight;//分配内存空间把源图存入内存int l_width = WIDTHBYTES(width* bitInfoHead.biBitCount);//计算位图的实际宽度并确保它为32的倍数BYTE *pColorData=(BYTE *)malloc(height*l_width);memset(pColorData,0,height*l_width);long nData = height*l_width;//把位图数据信息读到数组里fread(pColorData,1,nData,pfile);//将位图数据转化为RGB数据tagRGBQUAD* dataOfBmp;dataOfBmp = (tagRGBQUAD *)malloc(width*height*sizeof(tagRGBQUAD));//用于保存各像素对应的RGB数据memset(dataOfBmp,0,width*height*sizeof(tagRGBQUAD));if(bitInfoHead.biBitCount<24)//有调色板,即位图为非真彩色{int k;int index = 0;if (bitInfoHead.biBitCount == 1){for(int i=0;i<height;i++)for(int j=0;j<width;j++){BYTE mixIndex= 0;k = i*l_width + j/8;//k:取得该像素颜色数据在实际数据数组中的序号//j:提取当前像素的颜色的具体值mixIndex = pColorData[k];switch(j%8){case 0:mixIndex = mixIndex<<7;mixIndex = mixIndex>>7;break;case 1:mixIndex = mixIndex<<6;mixIndex = mixIndex>>7;break;case 2:mixIndex = mixIndex<<5;mixIndex = mixIndex>>7;break;case 3:mixIndex = mixIndex<<4;mixIndex = mixIndex>>7;break;case 4:mixIndex = mixIndex<<3;mixIndex = mixIndex>>7;break;case 5:mixIndex = mixIndex<<2;mixIndex = mixIndex>>7;break;case 6:mixIndex = mixIndex<<1;mixIndex = mixIndex>>7;break;case 7:mixIndex = mixIndex>>7;break;}//将像素数据保存到数组中对应的位置dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen; dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved; index++;}}if(bitInfoHead.biBitCount==2){for(int i=0;i<height;i++)for(int j=0;j<width;j++){BYTE mixIndex= 0;k = i*l_width + j/4;//k:取得该像素颜色数据在实际数据数组中的序号//j:提取当前像素的颜色的具体值mixIndex = pColorData[k];switch(j%4){case 0:mixIndex = mixIndex<<6;mixIndex = mixIndex>>6;break;case 1:mixIndex = mixIndex<<4;mixIndex = mixIndex>>6;break;case 2:mixIndex = mixIndex<<2;mixIndex = mixIndex>>6;break;case 3:mixIndex = mixIndex>>6;break;}//将像素数据保存到数组中对应的位置dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen; dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue;dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved;index++;}}if(bitInfoHead.biBitCount == 4){for(int i=0;i<height;i++)for(int j=0;j<width;j++){BYTE mixIndex= 0;k = i*l_width + j/2;mixIndex = pColorData[k];if(j%2==0){//低mixIndex = mixIndex<<4;mixIndex = mixIndex>>4;}else{//高mixIndex = mixIndex>>4;}dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed; dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen; dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue; dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved; index++;}}if(bitInfoHead.biBitCount == 8){for(int i=0;i<height;i++)for(int j=0;j<width;j++){BYTE mixIndex= 0;k = i*l_width + j;mixIndex = pColorData[k];dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed;dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen; dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue; dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved; index++;}}if(bitInfoHead.biBitCount == 16){for(int i=0;i<height;i++)for(int j=0;j<width;j++){WORD mixIndex= 0;k = i*l_width + j*2;WORD shortTemp;shortTemp = pColorData[k+1];shortTemp = shortTemp<<8;mixIndex = pColorData[k] + shortTemp;dataOfBmp[index].rgbRed = pRgb[mixIndex].rgbRed; dataOfBmp[index].rgbGreen = pRgb[mixIndex].rgbGreen; dataOfBmp[index].rgbBlue = pRgb[mixIndex].rgbBlue; dataOfBmp[index].rgbReserved = pRgb[mixIndex].rgbReserved; index++;}}}else//位图为24位真彩色{int k;int index = 0;for(int i=0;i<height;i++)for(int j=0;j<width;j++){k = i*l_width + j*3;dataOfBmp[index].rgbRed = pColorData[k+2];dataOfBmp[index].rgbGreen = pColorData[k+1];dataOfBmp[index].rgbBlue = pColorData[k];index++;}}printf("像素数据信息:\n");for (int i=0; i<width*height; i++) {if (i%5==0){printf("\n");}showRgbQuan(&dataOfBmp[i]); }fclose(pfile);if (bitInfoHead.biBitCount<24) {free(pRgb);}free(dataOfBmp);free(pColorData);printf("\n");}。

相关文档
最新文档