【c语言读取bmp】bmp做背景,在其上画圆的代码!!!

ffmpeg(15)
BMP是bitmap的缩写形式,bitmap顾名思义,就是位图也即Windows位图。它一般由4部分组成:文件头信息块、图像描述信息块、颜色表(在真彩色模式无颜色表)和图像数据区组成。在系统中以BMP为扩展名保存。&&&
&   打开Windows的画图程序,在保存图像时,可以看到三个选项:2色位图(黑白)、16色位图、256色位图和24位位图。这是最普通的生成位图的工具,在这里讲解的BMP位图形式,主要就是指用画图生成的位图(当然,也可以用其它工具软件生成)。&&&
&   现在讲解BMP的4个组成部分:&&&
& 1.文件头信息块&&&
& :文件标识,为字母ASCII码“BM”。&&&
& :文件大小。&&&
& :保留,每字节以“00”填写。&&&
& 000A-000D:记录图像数据区的起始位置。各字节的信息依次含义为:文件头信息块大小,图像描述信息块的大小,图像颜色表的大小,保留(为01)。&&&
& 2.图像描述信息块&&&
& 000E-0011:图像描述信息块的大小,常为28H。&&&
& :图像宽度。&&&
& :图像高度。&&&
& 001A-001B:图像的plane(平面?)总数(恒为1)。&&&
& 001C-001D:记录像素的位数,很重要的数值,图像的颜色数由该值决定。&&&
& 001E-0021:数据压缩方式(数值位0:不压缩;1:8位压缩;2:4位压缩)。&&&
& :图像区数据的大小。&&&
& :水平每米有多少像素,在设备无关位图(.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色模式时,一定要设置调色板或修正颜色值,否则无法得到正确的图像颜色。
&&&&#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&bfS&&&&&&&&&&&&&WORD&&&bfReserved1;&&&&&&&WORD&&&bfReserved2;&&&&&&&DWORD&bfOffB&&&&&&&&&&}&BITMAPFILEHEADER;&&&&&&&&&&&typedef&struct&tagBITMAPINFOHEADER{&&&&DWORD&&&biS&&&&&&&&&&&&&&&LONG&&&&biW&&&&&&&&&&&&&&LONG&&&&biH&&&&&&&&&&&&&WORD&&&&biP&&&&&&&&&&&&&WORD&&&&biBitC&&&&&&&&&&&DWORD&&&biC&&&&&&&&DWORD&&&biSizeI&&&&&&&&&&LONG&&&&biXPelsPerM&&&&&&LONG&&&&biYPelsPerM&&&&&&DWORD&&&biClrU&&&&&&&&&&&&DWORD&&&biClrI&&&&&&&}&BITMAPINFOHEADER;&&&&&&&&&&&&&typedef&struct&tagRGBQUAD&{&&&&&BYTE&&&&&rgbB&&&BYTE&&&&&rgbG&&&BYTE&&&&&rgbR&&&BYTE&&&&&rgbR&&&}&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&&&bitH&&BITMAPINFOHEADER&bitInfoH&&&FILE*&&&&&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&fileT&&&&&fread(&fileType,1,sizeof(WORD),pfile);&&&&&if(fileType&!=&0x4d42)&&&&&{&&&&&&printf(&file&is&not&.bmp&file!&);&&&&&&return;&&&&&}&&&&&&&&&&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)));&&&&&&&&&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&nPlantNi++)&&&&&{&&&&&&if&(i%5==0)&&&&&&{&&&&&&&printf(&\n&);&&&&&&}&&&&&&showRgbQuan(&pRgb[i]);&&&&&&&&&&}&&&&&&&printf(&\n&);&&&&&&}&&&&&&int&width&=&bitInfoHead.biW&&int&height&=&bitInfoHead.biH&&&&int&l_width&&&=&WIDTHBYTES(width*&bitInfoHead.biBitCount);&&BYTE&&&&*pColorData=(BYTE&*)malloc(height*l_width);&&&&&memset(pColorData,0,height*l_width);&&&&&long&nData&=&height*l_&&&&&&fread(pColorData,1,nData,pfile);&&&&&&&&&&&&&&&&&tagRGBQUAD*&dataOfB&&dataOfBmp&=&(tagRGBQUAD&*)malloc(width*height*sizeof(tagRGBQUAD));&&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&i++)&&&&&&&for(int&j=0;j&j++)&&&&&&&{&&&&&&&&BYTE&mixIndex=&0;&&&&&&&&k&=&i*l_width&+&j/8;&&&&&&&&&&&&&&&&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].rgbR&&&&&&&&dataOfBmp[index].rgbGreen&=&pRgb[mixIndex].rgbG&&&&&&&&dataOfBmp[index].rgbBlue&=&pRgb[mixIndex].rgbB&&&&&&&&dataOfBmp[index].rgbReserved&=&pRgb[mixIndex].rgbR&&&&&&&&index++;&&&&&&&&}&&&&&}&&&&&&&if(bitInfoHead.biBitCount==2)&&&&&{&&&&&&for(int&i=0;i&i++)&&&&&&&for(int&j=0;j&j++)&&&&&&&{&&&&&&&&BYTE&mixIndex=&0;&&&&&&&&k&=&i*l_width&+&j/4;&&&&&&&&&&&&&&&&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].rgbR&&&&&&&&dataOfBmp[index].rgbGreen&=&pRgb[mixIndex].rgbG&&&&&&&&dataOfBmp[index].rgbBlue&=&pRgb[mixIndex].rgbB&&&&&&&&dataOfBmp[index].rgbReserved&=&pRgb[mixIndex].rgbR&&&&&&&&index++;&&&&&&&&&&&}&&&&&}&&&&&if(bitInfoHead.biBitCount&==&4)&&&&&{&&&&&&for(int&i=0;i&i++)&&&&&&&for(int&j=0;j&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].rgbR&&&&&&&&dataOfBmp[index].rgbGreen&=&pRgb[mixIndex].rgbG&&&&&&&&dataOfBmp[index].rgbBlue&=&pRgb[mixIndex].rgbB&&&&&&&&dataOfBmp[index].rgbReserved&=&pRgb[mixIndex].rgbR&&&&&&&&index++;&&&&&&&&&}&&&&&&&}&&&&&if(bitInfoHead.biBitCount&==&8)&&&&&{&&&&&&for(int&i=0;i&i++)&&&&&&&for(int&j=0;j&j++)&&&&&&&{&&&&&&&&BYTE&mixIndex=&0;&&&&&&&&&&k&=&i*l_width&+&j;&&&&&&&&&&mixIndex&=&pColorData[k];&&&&&&&&&&dataOfBmp[index].rgbRed&=&pRgb[mixIndex].rgbR&&&&&&&&dataOfBmp[index].rgbGreen&=&pRgb[mixIndex].rgbG&&&&&&&&dataOfBmp[index].rgbBlue&=&pRgb[mixIndex].rgbB&&&&&&&&dataOfBmp[index].rgbReserved&=&pRgb[mixIndex].rgbR&&&&&&&&index++;&&&&&&&&&&&&&&&&&&&&&&&}&&&&&}&&&&&if(bitInfoHead.biBitCount&==&16)&&&&&{&&&&&&for(int&i=0;i&i++)&&&&&&&for(int&j=0;j&j++)&&&&&&&{&&&&&&&&WORD&mixIndex=&0;&&&&&&&&&&k&=&i*l_width&+&j*2;&&&&&&&&WORD&shortT&&&&&&&&shortTemp&=&pColorData[k+1];&&&&&&&&shortTemp&=&shortTemp&&8;&&&&&&&&&&&&&&mixIndex&=&pColorData[k]&+&shortT&&&&&&&&&&dataOfBmp[index].rgbRed&=&pRgb[mixIndex].rgbR&&&&&&&&dataOfBmp[index].rgbGreen&=&pRgb[mixIndex].rgbG&&&&&&&&dataOfBmp[index].rgbBlue&=&pRgb[mixIndex].rgbB&&&&&&&&dataOfBmp[index].rgbReserved&=&pRgb[mixIndex].rgbR&&&&&&&&index++;&&&&&&&}&&&&&}&&}&&else&&{&&&&&int&k;&&&&&int&index&=&0;&&&&&for(int&i=0;i&i++)&&&&&&for(int&j=0;j&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*&i++)&&{&&&&&if&(i%5==0)&&&&&{&&&&&&printf(&\n&);&&&&&}&&&&&showRgbQuan(&dataOfBmp[i]);&&}&&&&fclose(pfile);&&&if&(bitInfoHead.biBitCount&24)&&{&&&&&free(pRgb);&&}&&free(dataOfBmp);&&free(pColorData);&&printf(&\n&);&&&&}&&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:185934次
积分:3654
积分:3654
排名:第7930名
原创:145篇
转载:243篇
(4)(3)(27)(4)(1)(1)(3)(4)(12)(7)(3)(9)(3)(1)(2)(1)(3)(11)(9)(16)(12)(3)(3)(14)(14)(8)(14)(10)(27)(27)(40)(28)(21)(13)(20)(15)(1)(2)博客访问: 2511193
博文数量: 167
博客积分: 3918
博客等级: 少校
技术积分: 8319
注册时间:
个人微薄: /manuscola
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
& & 我知道C语言的能力很强,但是对于图形图像类的C语言实现很是好奇,觉得很难。我读书的时候,用C语言画过BMP格式的图像,因为没有任何的压缩,所以图像的数据量比较大,基本上就是RGB 字节流。今天看了Banu blog中的博文 Drawing circles,想起了以前用C语言进行BMP图像的处理。& & &写这篇博客,是给自己枯燥的学习带来一些乐趣,C语言也可以干些比较有有趣的事情。代码基本上是照搬Banu,只是,文章画的图像是灰度图像,不够靓丽,我将代码改成了生成彩色图像。不管怎么说,光荣属于Banu,我只是仰望前辈的学习者。& & 生成一个文件,后缀为ppm,Linux下的GIMP自然可以解析这种格式。ppm格式和BMP很像,基本属于傻瓜型图像格式,每个像素就是RGB三个字节表示,当然为了声明文件类型,会有文件头。看下WIKI中的介绍。& &&Magic NumberTypeEncodingP1Portable bitmapASCIIP2Portable graymapASCIIP3Portable pixmapASCIIP4Portable bitmapBinaryP5Portable graymapBinaryP6Portable pixmapBinaryP3&# The P3 means colors are in ASCII, then 3 columns and 2 rows,&# then 255 for max color, then RGB triplets&3 2&255&255
0 & & & 0 255
0 & & & &0
0 255&255 255
0 & & &255 255 255 & &0
0我们看到了上面虚框中的文件内容,画出来就是下面这个彩色图像。当然,下面的图用一个比较大的正方形来表示一个像素点(255,0,0)表示红色,所以代表第一个像素点的正方形是红色的,依次类推。OK,下面看下代码:static void
image_save (const Image *image,
&&&&&&&&&&&&const char
*filename)
&&FILE *out;
&&out = fopen (filename, "wb");
&&if (!out)
&&&&return;
&&fprintf (out, "P6\n");
&&fprintf (out, "%zu %zu\n", image->width, image->height);
&&fprintf (out, "255\n");
&&fwrite (image->data, 1, image->width * image->height*3, out);
&&fclose (out);
}P6告诉文件解析程序(如GIMP)我是PPM格式的文件(Portable pixmap)。第二行告诉文件的长和高。下面是完整的代码,再次强调,荣耀和版权都属于Banu,我只是仰望Banu的学习者。#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct {
&&unsigned char *data;
static Image *
image_new (size_t width,
&&&&&&&&&&&size_t height)
&&Image *image;
&&image = malloc (sizeof *image);
&&image->width = width;
&&image->height = height;
&&image->data = malloc (width * height*3);
&&return image;
static void
image_free (Image *image)
&&free (image->data);
&&free (image);
static void
image_fill (Image
&&&&&&&&&&&&unsigned char
&&memset (image->data, value, image->width * image->height*3);
&* image_set_pixel:
&* Sets a pixel passed in signed (x, y) coordinates, where (0,0) is at
&* the center of the image.
static void
image_set_pixel (Image
&&&&&&&&&&&&&&&&&ssize_t
&&&&&&&&&&&&&&&&&ssize_t
&&&&&&&&&&&&&&&&&unsigned char
Rvalue,& & & & & & & & &unsigned char
Gvalue,& & & & & & & & &unsigned char
&&size_t tx, ty;
&&unsigned char *p;
&&tx = (image->width / 2) + x;
&&ty = (image->height / 2) + y;
&&p = image->data + (ty * image->width*3) + tx*3;
&&*p = Rvalue;
&&&&*(p+1) = Gvalue;
&&&&*(p+2) = Bvalue;
static void
image_save (const Image *image,
&&&&&&&&&&&&const char
*filename)
&&FILE *out;
&&out = fopen (filename, "wb");
&&if (!out)
&&&&return;
&&fprintf (out, "P6\n");
&&fprintf (out, "%zu %zu\n", image->width, image->height);
&&fprintf (out, "255\n");
&&fwrite (image->data, 1, image->width * image->height*3, out);
&&fclose (out);
static void
draw_circle (Image
&&&&&&&&&&&&&int
&&&&&&&&&&&&&unsigned char
&&&&&&&&&&&&&&&&&&&&&&&& unsigned char
&&&&&&&&&&&&&&&&&&&&&&&& unsigned char
&&int x, y;
&&for (y = -radius; y <= radius; y++)
&&&&for (x = -radius; x <= radius; x++)
&&&&&&if ((x * x) + (y * y) <= (radius * radius))
&&&&&&&&image_set_pixel (image, x, y, Rvalue,Gvalue,Bvalue);
main (int argc, char *argv[])
&&Image *image;
&&image = image_new (600, 600);
&&image_fill (image, 0xff);
&&draw_circle (image, 200, 0x00,0x00,0xff);
&&image_save (image, "circle.ppm");
&&image_free (image);
&&return 0;
}就可以在本地查看一个蓝色的圆图像。下图格式是jpg格式的,我用QQ截图工具生成的。由于CU不支持ppm格式的图像,所以只能传jpg了。参考文献:1 Banu 博文 Drawing Circles2 Wiki
阅读(15219) | 评论(3) | 转发(4) |
相关热门文章
给主人留下些什么吧!~~
太神奇了,原来在当前目录下生成了一个circle.ppm的图片呀。
在fedora下gcc 通过,但是执行./文件名 的时候什么都没有显示。
请登录后评论。}

我要回帖

更多关于 c语言代码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信