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

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

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

android 通过矩阵修改图片大小 矩阵怎么做成图片_#define

android 通过矩阵修改图片大小 矩阵怎么做成图片_Code_02

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:%s\n", 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 }
  1. View Code

2.从外界导入的txt和csv保存为bmp图片将数据导入txt中:

android 通过矩阵修改图片大小 矩阵怎么做成图片_#define

android 通过矩阵修改图片大小 矩阵怎么做成图片_Code_02

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 }
  1. View Code

从txt中读取数据:

android 通过矩阵修改图片大小 矩阵怎么做成图片_#define

android 通过矩阵修改图片大小 矩阵怎么做成图片_Code_02

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 }
  1. View Code

将数据导入csv中:

android 通过矩阵修改图片大小 矩阵怎么做成图片_#define

android 通过矩阵修改图片大小 矩阵怎么做成图片_Code_02

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 %.2f\n", No, salary);//写入指针fp,写入的东西就是刚才的用户输入的d,注意这里的fp和d没有引号    
21     }
22     //关闭文件    
23     fclose(fp);
24 }
  1. View Code

从csv中读取数据:

android 通过矩阵修改图片大小 矩阵怎么做成图片_#define

android 通过矩阵修改图片大小 矩阵怎么做成图片_Code_02

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("%d\t%.2f\n", No, salary);//写入指针fp,写入的东西就是刚才的用户输入的d,注意这里的fp和d没有引号    
21     }
22     //关闭文件    
23     fclose(fp);
24     system("pause");
25 }
  1. View Code

将txt中的数据保存为bmp图片

android 通过矩阵修改图片大小 矩阵怎么做成图片_#define

android 通过矩阵修改图片大小 矩阵怎么做成图片_Code_02

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:%s\n", 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 exist\n", 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 }
  1. View Code

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

android 通过矩阵修改图片大小 矩阵怎么做成图片_#define

android 通过矩阵修改图片大小 矩阵怎么做成图片_Code_02

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:%s\n", 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 exist\n", 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 }
  1. View Code