使用C生成bmp图片(pixel阵列方式)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 6 typedef unsigned char byte; 7 typedef unsigned short dbyte; 8 typedef long int dword; 9 typedef unsigned short word; 10 11 12 /******************************************* 13 *定义bmp文件的头部数据结构 14 ********************************************/ 15 #pragma pack(push,2) //保持2字节对齐 16 17 18 struct tagBITMAPFILEHEADER { 19 //bmp file header 20 dbyte bfType; //文件类型 21 dword bfSize; //文件大小,字节为单位 22 word bfReserved1; //保留,必须为0 23 word bfReserved2; //保留,必须为0 24 dword bfOffBits; //从文件头开始的偏移量 25 26 27 //bmp info head 28 dword biSize; //该结构的大小 29 dword biWidth; //图像的宽度,以像素为单位 30 dword biHeight; //图像的高度,以像素为单位 31 word biPlanes; //为目标设备说明位面数,其值总是设为1 32 word biBitCount; //说明比特数/像素 33 dword biCompression; //图像数据压缩类型 34 dword biSizeImage; //图像大小,以字节为单位 35 dword biXPelsPerMeter; //水平分辨率,像素/米 36 dword biYPelsPerMeter; //垂直分辨率,同上 37 dword biClrUsed; //位图实际使用的彩色表中的颜色索引数 38 dword biClrImportant; //对图像显示有重要影响的颜色索引的数目 39 40 //bmp rgb quad 41 //对于16位,24位,32位的位图不需要色彩表 42 //unsigned char rgbBlue; //指定蓝色强度 43 //unsigned char rgbGreen; //指定绿色强度 44 //unsigned char rgbRed; //指定红色强度 45 //unsigned char rgbReserved; //保留,设置为0 46 }BMPFILEHEADER; 47 #pragma pack(2) 48 49 50 struct tagBITMAPFILEHEADER *bmp_p; //定义bmp文件头结构体指针 51 FILE *fd; //定义一个文件类型的指针 52 53 54 /************************************************************* 55 *初始化bmp文件头部,设置bmp图片 56 **************************************************************/ 57 58 // 计算每一行像素 4 字节对齐后的字节数 59 int caculateLineBytes(int width) 60 { 61 //******* 四字节对齐 ******* 62 return (width*3 + 3)/4 *4; 63 //******* 四字节对齐 ******* 64 } 65 66 int main(void) 67 { 68 //防止中文乱码 69 #ifdef _WIN32 70 SetConsoleOutputCP (65001); 71 #endif 72 73 FILE *fpin=fopen("base.txt","r"); //数据文件 74 static char *file_name =NULL; //保存文件名的指针 75 static long file_length; //文件的大小(整个文件) 76 unsigned char *file_p = NULL; //写入数据指针 77 unsigned char *file_p_tmp = NULL; //写入数据临时指针 78 unsigned char *byte_copy_p = NULL; //文件头部传递指针 79 unsigned char byte_copy = 0; //文件头部数据拷贝变量 80 int i, width; 81 printf("请新建文本文件并命名“base.txt”,再文件中分别输入分辨率x,y\n重复单元大小x,y,重复单元内容R,G,B;各项数据间以空格或者换行进行区分。\n程序只会取整进行计算,如果为浮点值,则舍去小数部分!\n"); 82 83 //bmp头信息 84 bmp_p = &BMPFILEHEADER; 85 bmp_p-> bfType = 0x4D42; //文件类型 86 87 bmp_p-> bfReserved1 = 0x0; //保留,必须为0 88 bmp_p-> bfReserved2 = 0x0; //保留,必须为0 89 bmp_p-> bfOffBits = 0x36; //从文件头开始的偏移量 90 91 //bmp info head 92 bmp_p-> biSize = 40; //该结构的大小 93 bmp_p-> biPlanes = 1; //为目标设备说明位面数,其值总是设为1 94 bmp_p-> biBitCount = 24; //说明比特数/像素 95 bmp_p-> biCompression = 0; //图像数据压缩类型(0为无压缩) 96 fscanf(fpin, "%ld", &bmp_p->biWidth);//读取图像宽度 97 width=caculateLineBytes(bmp_p->biWidth); //计算对齐后的实际图片宽度 98 fscanf(fpin, "%ld", &bmp_p->biHeight); 99 bmp_p->biHeight=-1*(bmp_p->biHeight);//读取图像高度,并转换读取方向 100 bmp_p-> biSizeImage=width*bmp_p->biHeight*(-1); //计算图像大小 101 102 bmp_p-> biXPelsPerMeter = 10000;//0x60; //水平分辨率,像素/米 103 bmp_p-> biYPelsPerMeter = 10000; //垂直分辨率,同上 104 bmp_p-> biClrUsed = 0; //位图实际使用的彩色表中的颜色索引数 105 bmp_p-> biClrImportant = 0; //对图像显示有重要影响的颜色索引的数目 106 //读取重复单元内容 107 int numx,numy,Ux,Uy,lastp; //存储重复单元 108 fscanf(fpin,"%d %d",&Ux,&Uy); //赋值数组 109 if(bmp_p->biWidth<Ux || -bmp_p->biHeight<Uy) //排除输入错误的情况 110 111 { 112 printf("重复单元必须大于等于图像分辨率!"); 113 getchar(); 114 return 0; 115 } 116 117 int Punit[Uy][Ux][3]; //定义unit数组 118 119 for(int i=0;i<Uy;i ++) 120 { 121 for(int j=0;j<Ux;j++) 122 { 123 if(feof(fpin)!=0) 124 { 125 printf("输入字符不够!请补充!"); 126 fclose(fpin); 127 getchar(); 128 return 0; 129 } 130 fscanf(fpin,"%d,%d,%d",&Punit[i][j][0],&Punit[i][j][1],&Punit[i][j][2]); 131 } 132 133 } 134 135 numx=(bmp_p->biWidth)/Ux; //列数 136 numy=-1*(bmp_p->biHeight/Uy); //行数 137 fclose(fpin); 138 139 file_name = "test1.bmp"; 140 file_length=bmp_p->biSizeImage+54; 141 bmp_p->bfSize =file_length;//实际文件大小 142 file_p = (unsigned char *)malloc(sizeof(char)*file_length); //申请一段内存 143 memset(file_p,0,sizeof(char)*file_length); //初始化为0 144 file_p_tmp = file_p; 145 int flag=width-Ux*numx*3,mi; //对行尾进行标记 146 //写入文件头和信息头 147 byte_copy_p = (unsigned char *)bmp_p; 148 file_p_tmp = file_p; 149 for(i = 0;i < 54;i++) 150 { 151 *file_p_tmp = *byte_copy_p; 152 file_p_tmp++; 153 byte_copy_p++; 154 } 155 //写入图像具体数据 156 for(int j=0;j<numy;j++)//对行单元重复数量操作 157 { 158 for(int l=0;l<Uy;l++)//对行重复 159 { 160 for(int i=0;i<numx;i++)//对列单元重复数量操作 161 { 162 for(int k=0;k<Ux;k++)//对列重复数量操作 163 { 164 165 *file_p_tmp=Punit[l][k][2]; //写入红色 166 file_p_tmp++; 167 *file_p_tmp=Punit[l][k][1]; //写入绿色 168 file_p_tmp++; 169 *file_p_tmp=Punit[l][k][0]; //写入蓝色 170 file_p_tmp++; 171 if (flag>0 && ((i*Ux+k+1)*3+flag==width)) 172 { 173 for(mi=0;mi<flag;mi++) 174 { 175 *file_p_tmp=0; 176 file_p_tmp++; 177 } 178 } 179 180 } 181 182 } 183 } 184 } 185 186 fd = fopen(file_name, "w"); 187 fwrite(file_p, file_length, 1,fd); 188 free(file_p); //释放申请的内存(重要) 189 fclose(fd); 190 fclose(fpin); 191 printf("Done success!!!\n"); 192 getchar(); 193 return (0); 194 }
需要在同目录下设置base.txt文件,并输入数据;
使用vs code搭配minGW 64编译完成。
数组生成部分不规范,但是可以用minGW编译完成
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述