纯C++代码实现将像素矩阵保存为bmp图片

由于工作需要,时常需要将像素矩阵保存图片显示观看。为此,特地总结了三种使用纯C++代码生成bmp图片的方法。分别是使用自定义数据、从外界导入的txt和csv以及从图片中导入的数据。

  1. 1.使用自定义数据保存为bmp图片

    自定义数据可以是使用公式生成,或者是根据自己需求自己定义的数据,范围为0-255,分别对应从黑色到白色。代码生成过程如下:

    纯C++代码实现将像素矩阵保存为bmp图片纯C++代码实现将像素矩阵保存为bmp图片

1 #pragma warning(disable:4996)  2 #include<iostream>  3 #include<string>  4 using namespace std;  5   6 //#define FrameSize 960*960  //视频帧大小  7 int width = 120, height = 120;  8 #define FrameNum 300       //yuv帧数  9 static const double S_PI = 3.14159265358979323846; 10 #define scos(x)         cos((double)(x)) 11 #define stan(x)         tan((double)(x)) 12 #define ssqrt(x)        sqrt((double)(x)) 13 #define ET_SIZE 300 14 char errorText[ET_SIZE]; 15  16 void errorMsg(const char *msg)  17 { 18     printf("error:%sn", msg); 19 #ifdef _WIN32 20     system("pause"); 21 #endif 22     exit(-1); 23 } 24  25 void readSequence(unsigned char *frames) 26 { 27     //Test start     28     for (int y = 0; y < height; y++) 29     { 30         for (int x = 0; x < width; x++) 31         { 32             //使用公式生成像素数据 33             float pu0 = (float)((2.0*(x + 0.5)) / width - 1.0); 34             float pv0 = (float)((2.0*(y + 0.5)) / height - 1.0); 35  36             double tu0 = stan(pu0*S_PI / 4.0); 37             double tv0 = stan(pv0*S_PI / 4.0); 38             double value= 1.0 / (scos(pu0*S_PI / 4.0)*scos(pu0*S_PI / 4.0)*scos(pv0*S_PI / 4.0)*scos(pv0*S_PI / 4.0) * (tu0*tu0 + tv0*tv0 + 1.0) * ssqrt(tu0*tu0 + tv0*tv0 + 1.0)); 39  40             //将值从(0,1)放大到(0,255) 41             value= 255.0*value; 42             //将值从(128,255)放大到(0,255),增加图像对比度 43             frames[y*width + x] = 2.0*value- 255.0; 44         } 45     } 46 } 47  48 void write_bmpheader(unsigned char *bitmap, int offset, int bytes, int value)  49 { 50     int i; 51     for (i = 0; i < bytes; i++) 52         bitmap[offset + i] = (value >> (i << 3)) & 0xFF; 53 } 54  55 unsigned char *convertToBmp(unsigned char *inputImg, int width, int height, int *ouputSize)  56 { 57     /*create a bmp format file*/ 58     int bitmap_x = (int)ceil((double)width * 3 / 4) * 4; 59     unsigned char *bitmap = (unsigned char*)malloc(sizeof(unsigned char)*height*bitmap_x + 54); 60  61     bitmap[0] = 'B'; 62     bitmap[1] = 'M'; 63     write_bmpheader(bitmap, 2, 4, height*bitmap_x + 54); //whole file size 64     write_bmpheader(bitmap, 0xA, 4, 54); //offset before bitmap raw data 65     write_bmpheader(bitmap, 0xE, 4, 40); //length of bitmap info header 66     write_bmpheader(bitmap, 0x12, 4, width); //width 67     write_bmpheader(bitmap, 0x16, 4, height); //height 68     write_bmpheader(bitmap, 0x1A, 2, 1); 69     write_bmpheader(bitmap, 0x1C, 2, 24); //bit per pixel 70     write_bmpheader(bitmap, 0x1E, 4, 0); //compression 71     write_bmpheader(bitmap, 0x22, 4, height*bitmap_x); //size of bitmap raw data 72  73     for (int i = 0x26; i < 0x36; i++) 74         bitmap[i] = 0; 75     int k = 54; 76     for (int i = height - 1; i >= 0; i--) { 77         int j; 78         for (j = 0; j < width; j++) { 79             int index = i*width + j; 80             for (int l = 0; l < 3; l++) 81                 bitmap[k++] = inputImg[index]; 82         } 83         j *= 3; 84         while (j < bitmap_x) { 85             bitmap[k++] = 0; 86             j++; 87         } 88     } 89     *ouputSize = k; 90     return bitmap; 91 } 92  93 void saveToBmp(unsigned char *inputImg, int width, int height, char *outputFileName)  94 { 95     int size; 96     unsigned char *bmp = convertToBmp(inputImg, width, height, &size); 97     FILE *fp = fopen(outputFileName, "wb+"); 98     if (fp == NULL) { 99         sprintf(errorText, "Could not open file: %s", outputFileName);100         errorMsg(errorText);101     }102     fwrite(bmp, 1, size, fp);103     fclose(fp);104     free(bmp);105 }106 int main() 107 {108     unsigned char *oriFrames;109     oriFrames = (unsigned char*)malloc(sizeof(unsigned char) * width * height);110     readSequence(oriFrames);111 112     char imgName[30];113     sprintf(imgName, "F:\pictures\Bitmap_Weight_Map_Convex2.bmp");114     //矩阵oriFrames[i]可以是任何你想保存为图片的像素矩阵,这里是yuv视频图像每一帧的像素数据115     saveToBmp(oriFrames, width, height, imgName);116     //system("pause");117 }

View Code

  1. 2.从外界导入的txt和csv保存为bmp图片

    将数据导入txt中:

    纯C++代码实现将像素矩阵保存为bmp图片纯C++代码实现将像素矩阵保存为bmp图片

1 #pragma warning(disable:4996) 2 #include <stdio.h> 3 #include <stdlib.h> 4 int main() 5 { 6     //文件写操作txt 7     FILE *fp;//文件指针     8     int i, d;      9     /*文件的打开*/10     fp = fopen("E:\VS_Test_Code\data.txt", "w");//fopen打开文件,这个文件可以是当前不存在的。“w”以写入的形式打开,“r”以读的形式打开    11     if (fp == NULL) //判断如果文件指针为空    12     {13         printf("File cannot open! ");14         exit(0);//在以0的形式退出,必须在文件开头有#include <stdlib.h>,stdlib 头文件即standard library标准库头文件    15     }16     //写入数据   17     for (i = 0; i < 10; i++)18     {19         scanf("%d", &d);//用户输入        20         fprintf(fp, "%d,", d);//写入指针fp,写入的东西就是刚才的用户输入的d,注意这里的fp和d没有引号    21     }22     //关闭文件    23     fclose(fp);24 }

View Code

从txt中读取数据:
纯C++代码实现将像素矩阵保存为bmp图片纯C++代码实现将像素矩阵保存为bmp图片

1 #pragma warning(disable:4996)
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 int main()
 5 {
 6     //文件读操作txt
 7     FILE *fp;//文件指针    
 8     int i, d;     
 9     /*文件的打开*/
10     fp = fopen("E:\VS_Test_Code\data.txt", "r");//fopen打开文件,这个文件可以是当前不存在的。“w”以写入的形式打开,“r”以读的形式打开    
11     if (fp == NULL) //判断如果文件指针为空    
12     {
13         printf("File cannot open! ");
14         exit(0);//在以0的形式退出,必须在文件开头有#include <stdlib.h>,stdlib 头文件即standard library标准库头文件    
15     }
16     int *array = (int*)malloc(sizeof(int) * 10);
17     //读取数据   
18     for (i = 0; i < 10; i++)
19     {
20         fscanf(fp, "%d,", &array[i]);//从文件输入        
21         printf("%d ", array[i]);//写入指针fp,写入的东西就是刚才的用户输入的d,注意这里的fp和d没有引号    
22     }
23     printf("n");
24     //关闭文件    
25     fclose(fp);
26     system("pause");//使窗口保持不关闭
27 }

View Code

将数据导入csv中:
纯C++代码实现将像素矩阵保存为bmp图片纯C++代码实现将像素矩阵保存为bmp图片

1 #pragma warning(disable:4996)
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 int main()
 5 {
 6     //文件写操作csv
 7     FILE *fp;//文件指针    
 8     int i, No;
 9     double salary;
10     fp = fopen("E:\VS_Test_Code\data.csv", "w");//fopen打开文件,这个文件可以是当前不存在的。“w”以写入的形式打开,“r”以读的形式打开    
11     if (fp == NULL) //判断如果文件指针为空    
12     {
13         printf("File cannot open! ");
14         exit(0);//在以0的形式退出,必须在文件开头有#include <stdlib.h>,stdlib 头文件即standard library标准库头文件    
15     }
16     //写入数据   
17     for (i = 0; i < 5; i++)
18     {
19         scanf("%d %lf", &No, &salary);//用户输入,double一定要用%lf        
20         fprintf(fp, "%d %.2fn", No, salary);//写入指针fp,写入的东西就是刚才的用户输入的d,注意这里的fp和d没有引号    
21     }
22     //关闭文件    
23     fclose(fp);
24 }

View Code

从csv中读取数据:
纯C++代码实现将像素矩阵保存为bmp图片纯C++代码实现将像素矩阵保存为bmp图片

1 #pragma warning(disable:4996)
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 int main()
 5 {
 6     //文件读操作csv
 7     FILE *fp;//文件指针    
 8     int i, No;
 9     double salary;
10     fp = fopen("E:\VS_Test_Code\data.csv", "r");//fopen打开文件,这个文件可以是当前不存在的。“w”以写入的形式打开,“r”以读的形式打开    
11     if (fp == NULL) //判断如果文件指针为空    
12     {
13         printf("File cannot open! ");
14         exit(0);//在以0的形式退出,必须在文件开头有#include <stdlib.h>,stdlib 头文件即standard library标准库头文件    
15     }
16     //读取数据   
17     for (i = 0; i < 5; i++)
18     {
19         fscanf(fp, "%d %lf", &No, &salary);//用户输入,double要用%lf        
20         printf("%dt%.2fn", No, salary);//写入指针fp,写入的东西就是刚才的用户输入的d,注意这里的fp和d没有引号    
21     }
22     //关闭文件    
23     fclose(fp);
24     system("pause");
25 }

View Code

将txt中的数据保存为bmp图片
纯C++代码实现将像素矩阵保存为bmp图片纯C++代码实现将像素矩阵保存为bmp图片

1 #pragma warning(disable:4996)
  2 #include<iostream>
  3 #include<string>
  4 using namespace std;
  5 
  6 #define FrameSize 100*100  //视频帧大小
  7 #define FrameNum 10       //yuv帧数
  8 #define ET_SIZE 300
  9 char errorText[ET_SIZE];
 10 
 11 void errorMsg(const char *msg) {
 12 
 13     printf("error:%sn", msg);
 14 
 15 #ifdef _WIN32
 16 
 17     system("pause");
 18 
 19 #endif
 20 
 21     exit(-1);
 22 
 23 }
 24 
 25 void readSequence(char *fileName, unsigned char **frames)
 26 {
 27     FILE *fp = fopen(fileName, "rb");
 28     if (fp == NULL)
 29     {
 30         sprintf(errorText, "File %s doesn't existn", fileName);
 31         errorMsg(errorText);
 32     }
 33 
 34     int uvSize = FrameSize / 2;            //H.264编解码获得的关键帧都是彩色序列,这里主要是提取亮度分量Y。
 35     unsigned char *buf = (unsigned char *)malloc(sizeof(unsigned char) * uvSize);
 36     for (int i = 0; i < FrameNum; i++) {
 37         //read y
 38         if (fread(frames[i], 1, FrameSize, fp) != FrameSize) {  //每一个keyFrames[i]分配的是 (unsigned char) * FrameSize的大小,所以fread要读的每个数据项的字节数为1,可以表示每个像素点亮度范围0~255
 39             sprintf(errorText, "Input sequence %s is not enough", fileName);
 40             errorMsg(errorText);
 41         }
 42 
 43         //read u,v
 44         fread(buf, 1, uvSize, fp);
 45     }
 46     free(buf);
 47     fclose(fp);
 48 }
 49 
 50 void write_bmpheader(unsigned char *bitmap, int offset, int bytes, int value) {
 51     int i;
 52     for (i = 0; i < bytes; i++)
 53         bitmap[offset + i] = (value >> (i << 3)) & 0xFF;
 54 }
 55 
 56 unsigned char *convertToBmp(unsigned char *inputImg, int width, int height, int *ouputSize) {
 57 
 58     /*create a bmp format file*/
 59     int bitmap_x = (int)ceil((double)width * 3 / 4) * 4;
 60     unsigned char *bitmap = (unsigned char*)malloc(sizeof(unsigned char)*height*bitmap_x + 54);
 61 
 62     bitmap[0] = 'B';
 63     bitmap[1] = 'M';
 64     write_bmpheader(bitmap, 2, 4, height*bitmap_x + 54); //whole file size
 65     write_bmpheader(bitmap, 0xA, 4, 54); //offset before bitmap raw data
 66     write_bmpheader(bitmap, 0xE, 4, 40); //length of bitmap info header
 67     write_bmpheader(bitmap, 0x12, 4, width); //width
 68     write_bmpheader(bitmap, 0x16, 4, height); //height
 69     write_bmpheader(bitmap, 0x1A, 2, 1);
 70     write_bmpheader(bitmap, 0x1C, 2, 24); //bit per pixel
 71     write_bmpheader(bitmap, 0x1E, 4, 0); //compression
 72     write_bmpheader(bitmap, 0x22, 4, height*bitmap_x); //size of bitmap raw data
 73 
 74     for (int i = 0x26; i < 0x36; i++)
 75         bitmap[i] = 0;
 76 
 77     int k = 54;
 78     for (int i = height - 1; i >= 0; i--) {
 79         int j;
 80         for (j = 0; j < width; j++) {
 81             int index = i*width + j;
 82             for (int l = 0; l < 3; l++)
 83                 bitmap[k++] = inputImg[index];
 84         }
 85         j *= 3;
 86         while (j < bitmap_x) {
 87             bitmap[k++] = 0;
 88             j++;
 89         }
 90     }
 91 
 92     *ouputSize = k;
 93     return bitmap;
 94 }
 95 
 96 void saveToBmp(unsigned char *inputImg, int width, int height, char *outputFileName) {
 97     int size;
 98     unsigned char *bmp = convertToBmp(inputImg, width, height, &size);
 99     FILE *fp = fopen(outputFileName, "wb+");
100     if (fp == NULL) {
101         sprintf(errorText, "Could not open file: %s", outputFileName);
102         errorMsg(errorText);
103 
104     }
105     fwrite(bmp, 1, size, fp);
106     fclose(fp);
107     free(bmp);
108 }
109 
110 int main() {
111     int width = 120, height = 120;
112 
113     unsigned char **oriFrames;
114     oriFrames = (unsigned char**)malloc(sizeof(unsigned char*) * FrameNum);
115     for (int i = 0; i < FrameNum; i++) {
116         oriFrames[i] = (unsigned char*)malloc(sizeof(unsigned char) * FrameSize);
117     }
118 
119     ////Test写入
120     //readSequence("E:\Research\YUV_Sequences\2D\BasketballPass_416x240_50\BasketballPass_416x240_50.yuv", oriFrames);
121     //FILE *fp;
122     //fp = fopen("E:\VS_Test_Code\cnblogData.txt", "w");
123     //if (fp == NULL)
124     //{
125     //    exit(0);
126     //}
127     //for (int i = 0; i < FrameNum; i++)
128     //{
129     //    for (int j = 0; j < FrameSize; j++)
130     //    {
131     //        fprintf(fp, "%d,", oriFrames[i][j]);
132     //    }
133     //    fprintf(fp, "n");
134     //}
135     ////Test写入
136 
137     //Test读取
138     FILE *fp;
139     fp = fopen("E:\VS_Test_Code\cnblogData.txt", "r");
140     if (fp == NULL)
141     {
142         exit(0);
143     }
144     for (int i = 0; i < FrameNum; i++)
145     {
146         for (int j = 0; j < FrameSize; j++)
147         {
148             fscanf(fp, "%d,", &oriFrames[i][j]);//必须和fprintf格式保持一致
149         }
150     }
151     for (int i = 0; i < FrameNum; i++)
152     {
153         for (int j = 0; j < FrameSize; j++)
154         {
155             printf("%d ", oriFrames[i][j]);
156         }
157         printf("n");
158     }
159     //Test读取
160 
161     char imgName[30];
162     for (int i = 0; i < FrameNum; i++) {
163         sprintf(imgName, "F:\pictures\ReconsFrame%d.bmp", i);
164         //矩阵oriFrames[i]可以是任何你想保存为图片的像素矩阵,这里是yuv视频图像每一帧的像素数据
165         saveToBmp(oriFrames[i], width, height, imgName);
166     }
167     system("pause");
168 }

View Code

  1. 3.从图片中导入的数据保存为bmp图片

    从图片中导入图像数据,将其存储为像素矩阵,像素值的范围是0-255,分别对应从黑色到白色,并将像素矩阵保存为bmp图片。代码如下所示:

    纯C++代码实现将像素矩阵保存为bmp图片纯C++代码实现将像素矩阵保存为bmp图片

1 #pragma warning(disable:4996)  2 #include<iostream>  3 #include<string>  4 using namespace std;  5   6 #define FrameSize 416*240  //视频帧大小  7 #define FrameNum 300       //yuv帧数  8 #define ET_SIZE 300  9 char errorText[ET_SIZE]; 10  11 void errorMsg(const char *msg)  12 { 13     printf("error:%sn", msg); 14 #ifdef _WIN32 15     system("pause"); 16 #endif 17     exit(-1); 18  19 } 20  21 void readSequence(char *fileName, unsigned char **frames)  22 { 23     FILE *fp = fopen(fileName, "rb"); 24     if (fp == NULL) 25     { 26         sprintf(errorText, "File %s doesn't existn", fileName); 27         errorMsg(errorText); 28     } 29     int uvSize = FrameSize / 2;            //H.264编解码获得的关键帧都是彩色序列,这里主要是提取亮度分量Y。 30     unsigned char *buf = (unsigned char *)malloc(sizeof(unsigned char) * uvSize); 31     for (int i = 0; i < FrameNum; i++) { 32         //read y 33         if (fread(frames[i], 1, FrameSize, fp) != FrameSize) {  //每一个keyFrames[i]分配的是 (unsigned char) * FrameSize的大小,所以fread要读的每个数据项的字节数为1,可以表示每个像素点亮度范围0~255 34             sprintf(errorText, "Input sequence %s is not enough", fileName); 35             errorMsg(errorText); 36         } 37         //read u,v 38         fread(buf, 1, uvSize, fp); 39     } 40     free(buf); 41     fclose(fp); 42 } 43  44  45  46 void write_bmpheader(unsigned char *bitmap, int offset, int bytes, int value)  47 { 48     int i; 49     for (i = 0; i < bytes; i++) 50         bitmap[offset + i] = (value >> (i << 3)) & 0xFF; 51 } 52  53 unsigned char *convertToBmp(unsigned char *inputImg, int width, int height, int *ouputSize)  54 { 55     /*create a bmp format file*/ 56     int bitmap_x = (int)ceil((double)width * 3 / 4) * 4; 57     unsigned char *bitmap = (unsigned char*)malloc(sizeof(unsigned char)*height*bitmap_x + 54); 58  59     bitmap[0] = 'B'; 60     bitmap[1] = 'M'; 61     write_bmpheader(bitmap, 2, 4, height*bitmap_x + 54); //whole file size 62     write_bmpheader(bitmap, 0xA, 4, 54); //offset before bitmap raw data 63     write_bmpheader(bitmap, 0xE, 4, 40); //length of bitmap info header 64     write_bmpheader(bitmap, 0x12, 4, width); //width 65     write_bmpheader(bitmap, 0x16, 4, height); //height 66     write_bmpheader(bitmap, 0x1A, 2, 1); 67     write_bmpheader(bitmap, 0x1C, 2, 24); //bit per pixel 68     write_bmpheader(bitmap, 0x1E, 4, 0); //compression 69     write_bmpheader(bitmap, 0x22, 4, height*bitmap_x); //size of bitmap raw data 70  71     for (int i = 0x26; i < 0x36; i++) 72         bitmap[i] = 0; 73  74     int k = 54; 75     for (int i = height - 1; i >= 0; i--) { 76         int j; 77         for (j = 0; j < width; j++) { 78             int index = i*width + j; 79             for (int l = 0; l < 3; l++) 80                 bitmap[k++] = inputImg[index]; 81         } 82         j *= 3; 83         while (j < bitmap_x) { 84             bitmap[k++] = 0; 85             j++; 86         } 87     } 88  89     *ouputSize = k; 90     return bitmap; 91 } 92  93 void saveToBmp(unsigned char *inputImg, int width, int height, char *outputFileName)  94 { 95     int size; 96     unsigned char *bmp = convertToBmp(inputImg, width, height, &size); 97     FILE *fp = fopen(outputFileName, "wb+"); 98     if (fp == NULL) { 99         sprintf(errorText, "Could not open file: %s", outputFileName);100         errorMsg(errorText);101 102     }103     fwrite(bmp, 1, size, fp);104     fclose(fp);105     free(bmp);106 }107 108 int main() 109 {110     int width = 416, height = 240;111 112     unsigned char **oriFrames;113     oriFrames = (unsigned char**)malloc(sizeof(unsigned char*) * FrameNum);114     for (int i = 0; i < FrameNum; i++) {115         oriFrames[i] = (unsigned char*)malloc(sizeof(unsigned char) * FrameSize);116     }117 118     //获取图像的数据119     readSequence("E:\Research\YUV_Sequences\2D\BasketballPass_416x240_50\BasketballPass_416x240_50.yuv", oriFrames);120 121     char imgName[30];122     for (int i = 0; i < 10 /*FrameNum*/; i++) {123         sprintf(imgName, "F:\pictures\ReconsFrame%d.bmp", i);124         //矩阵oriFrames[i]可以是任何你想保存为图片的像素矩阵,这里是yuv视频图像每一帧的像素数据125         saveToBmp(oriFrames[i], width, height, imgName);126     }127 }

View Code

  1. 4.参考文献

    https://blog.csdn.net/sinat_33718563/article/details/79424981

    https://blog.csdn.net/zzwtyds/article/details/75095698

原文链接: https://www.cnblogs.com/ipersevere/p/12756048.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/196368

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午7:13
下一篇 2023年2月12日 下午7:14

相关推荐