首页 > 编程知识 正文

c语言位图(c位图什么意思)

时间:2023-05-04 07:22:26 阅读:72634 作者:831

位图图像文件的缩放(c )前言)在c语言的课程设计中需要实现位图图像的缩放,但由于没有得到详细的位图图像的理解,所以需要相当大的工夫。 这里为了参考进行整理,如果有不恰当的地方想修改

了解位图图像(24位)本文仅介绍biBitCount=24的位图图像。 此外,代码仅适用于24位图像,没有压缩

定义由多个像素点组成的图像

构成元素共有三个

包括位图文件头部数据结构、包含BMP图像文件的类型、显示内容等信息的位图信息数据结构、定义BMP图像的宽度、高度、压缩方法、颜色等信息的每个像素的点信息(主要部分)结构体定义头部文件

#includewindows.h

bitmap文件头typedefstructtagbitmapfileheader wordbftype; 0 x4d 42固定到dword BF size//文件大小WORD bfReserved1; //保留字WORD bfReserved2; //保留字DWORD bfOffBits; //实际位图数据的偏移字节数,即前两部分长度之和} BITMAPFILEHEADER、*LPBITMAPFILEHEADER、*PBITMAPFILEHEADER; BITMAPINFOHEADER (对应信息数据) typedefstructtagbitmapinfoheader ) Dwordbisize; //指定此结构的长度,40长bi width; //位图宽度(单位:像素) LONG biHeight; //位图高度(单位:像素) WORD biPlanes; //平面数,1个1 WORD biBitCount; //采用颜色位数,1 2 4 8 16 24 32 DWORD biCompression; //压缩方案可以是0 1 2。 其中,0表示不压缩DWORD biSizeImage; //实际位图数据消耗的字节数LONG biXPelsPerMeter; //X方向分辨率LONG biYPelsPerMeter; //Y方向分辨率DWORD biClrUsed; //使用的颜色数DWORD biClrImportant; //重要颜色数(bitmapinfoheader、*LPBITMAPINFOHEADER、*PBITMAPINFOHEADER; 每个属性的具体含义是这里

看起来属性很多。 请注意这些:

biWidthbiHeightbiBitCount本节主要介绍如何存储biBitCount和像素点

可以将biBitCount看作是以多少位二进制数为每个像素点编写的。 例如,biBitCount=24由每像素点24位二进制数表示,每像素点由三个颜色通道(rgb )构成,因此每个颜色通道由八位二进制数(1字节)构成

所以,只要按顺序存储新的像素单位就可以了。 但是,这里有比较有漏洞的地方。 是位图规定每一行元素的大小必须是4byte的整数倍。 也就是说,如果每行有一个像素点,即24位,则必须在每行的末尾填充8bit。 这个8bit数据没有任何意义。 但是,为了对齐4字节整数倍的主要算法,计算缩放后的图像的height和width (单位:像素点数),扫描目标图像的各个像素点,找到在源图像中的位置,在http://www.Sina

在上图中,目标图像的一个像素点(e )位于源图像的位置。 其中,x和y都是整数,e点必须位于源图像的一个像素框中。 f ) e )表示e点的一个颜色通道的值,可以通过双线性插值求出

f(e )=dxdyf ) ) 1dx

) ( 1 − d y ) F ( D ) + ( 1 − d x ) d y F ( A ) + d x ( 1 − d y ) F ( C ) F(E)=dxdyF(B) +(1-dx)(1-dy)F(D)+(1-dx)dyF(A)+dx(1-dy)F(C) F(E)=dxdyF(B)+(1−dx)(1−dy)F(D)+(1−dx)dyF(A)+dx(1−dy)F(C) 代码

运行方法
例如源程序名为 convert.cpp 源图像名 cat.bmp 且在同一路径下
目标图像名为 cat_a.bmp 需要放大1.5倍
编译好后,在命令行输入
convert cat.bmp 150 cat_a.bmp

/*@auther:gtyinstinct*//*该程序只能处理biBitCount为24的bmp图片*/#include<bits/stdc++.h>#include<windows.h>#define WIDTHBYTES(bits) (((bits)+31)/32*4)//用于使图像宽度所占字节数为4byte的倍数 using namespace std;int bmpwidth,bmpheight; //原图像的宽度和高度(单位:像素)int src_width,dest_width; //实际存储每一行宽度(单位:字节)int new_bmpwidth,new_bmpheight;//新图像的宽度和高度(单位:像素)unsigned char *pBmpBuf; //存储原图像像素数据unsigned char *new_pBmpBuf; //存储新图像像素数据BITMAPFILEHEADER header;//位图文件头BITMAPINFOHEADER info;//位图文件信息int idx(int i,int j,int k){return i*src_width + j*3 + k;}int idx_n(int i,int j,int k){return i*dest_width + j*3 + k;}unsigned char process(int i1,int i2,int j1,int j2,int k,double i_t,double j_t){unsigned int tmp[] = {pBmpBuf[idx(i1,j1,k)], pBmpBuf[idx(i1,j2,k)], pBmpBuf[idx(i2,j1,k)], pBmpBuf[idx(i2,j2,k)]};unsigned int ret = (unsigned int)(tmp[0] * (1-i_t) * (1-j_t) + tmp[1] * (1-i_t) * j_t + tmp[2] * i_t * (1-j_t) + tmp[3] * i_t * j_t);return (unsigned char) ret;}bool convert(char *bmpName,char *new_bmpName,double scale){/*检查缩放比例是否正确*/if(scale <=0){cout << "scale is not correct" << endl;return 0;}/*以二进制的方式打开文件*/ FILE *src,*dest;dest = fopen(new_bmpName,"wb"); if( (src = fopen(bmpName,"rb")) == NULL) { cout<<"File "<< bmpName <<"failed to open"<<endl; return 0; } /*读取文件头和位图信息*/fread(&header,sizeof(BITMAPFILEHEADER),1,src); fread(&info,sizeof(BITMAPINFOHEADER),1,src); /*获取并打印位图大小*/ bmpwidth = info.biWidth; bmpheight = info.biHeight;if(info.biBitCount!=24){cout << "biBitCount is not equal to 24" << endl;return 0;} cout << "source image:" << endl; cout << "width:" << bmpwidth << " height:" << bmpheight << endl;/*计算缩放后的位图大小*/new_bmpwidth = (int) (bmpwidth*scale); new_bmpheight = (int) (bmpheight*scale); cout << "dest image:" << endl;cout << "width:" << new_bmpwidth << " height:" << new_bmpheight << endl;/*修改位图信息的大小信息*/info.biWidth = new_bmpwidth;info.biHeight = new_bmpheight;/*计算位图的实际宽度并确保是4byte的倍数*/src_width = WIDTHBYTES(bmpwidth*info.biBitCount);dest_width = WIDTHBYTES(new_bmpwidth*info.biBitCount);/*写入新位图的位图信息和文件头*/fwrite(&header,sizeof(BITMAPFILEHEADER),1,dest);fwrite(&info,sizeof(BITMAPINFOHEADER),1,dest);/*读取原位图的像素阵列*/ pBmpBuf = new unsigned char[bmpheight*src_width]; fread(pBmpBuf,sizeof(unsigned char),bmpheight*src_width,src);/*计算新位图的像素阵列并写入*/new_pBmpBuf = new unsigned char[dest_width*new_bmpheight];for(int i=0;i<new_bmpheight;i++){for(int j=0;j<new_bmpwidth;j++){double i_,j_;i_ = 1.0 * i * (bmpheight-1) / (new_bmpheight-1);j_ = 1.0 * j * (bmpwidth-1) / (new_bmpwidth-1);int i1,i2,j1,j2;i1 = (int)i_;j1 = (int)j_;i2 = i1 + 1;j2 = j1 + 1;double i_t,j_t;i_t = i_ - i1;j_t = j_ - j1;for(int k=0;k<3;k++){new_pBmpBuf[idx_n(i,j,k)] = process(i1,i2,j1,j2,k,i_t,j_t);}}}fwrite(new_pBmpBuf,sizeof(unsigned char),dest_width*new_bmpheight,dest);/*关闭文件*/ fclose(src); fclose(dest); return 1;} int main(int argc,char** argv){if(convert(argv[1],argv[3],(double)atoi(argv[2])/100))cout << "convert successfully";else cout << "fail to convert"; return 0;}/*@auther:gtyinstinct*/

ps:仅供参考,xder别直接拿源码交差

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。