文章目录
一、元素分离
#include <stdio.h>
#include <stdlib.h>
int rgb24Split(char* fileName, int width, int height)
{
FILE* fp = fopen(fileName, "rb+");
FILE* fp1 = fopen("1_r.y", "wb+");
FILE* fp2 = fopen("1_g.y", "wb+");
FILE* fp3 = fopen("1_b.y", "wb+");
unsigned char* readBuf = (unsigned char*)malloc(width * height * 3);
fread(readBuf, 1, width * height * 3, fp);
for (int i = 0; i < width * height * 3; i = i + 3)
{
//R
fwrite(readBuf + i, 1, 1, fp1);
//G
fwrite(readBuf + i + 1, 1, 1, fp2);
//B
fwrite(readBuf + i + 2, 1, 1, fp3);
}
free(readBuf);
fclose(fp);
fclose(fp1);
fclose(fp2);
fclose(fp3);
return 0;
}
int main()
{
rgb24Split("1.rgb", 1920, 1080);
return 0;
}
我这里没有图片素材,所以我是直接用YUV图片转过来的,所以显示也有点问题,毕竟YUV分量和RGB的占比不一样,但是不影响效果
从图片可以看出不同的分量显示是不一样的,这里最好选择一些颜色区别比较大的图,彩虹那种,更加明细。
二、RGB封装为BMP
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int rgb24_to_bmp(const char* rgb24path, int width, int height, const char* bmppath)
{
typedef struct
{
unsigned int imageSize; //文件大小
unsigned int blank; //位图文件保留字,必须为0
unsigned int startPosition; //位图头文件头到数据的偏移量
}BmpHead;
typedef struct
{
unsigned int Length; //结构大小
unsigned int width; //图像宽度
unsigned int height; //图像长度
unsigned short colorPlane; //目标设备级别,必须为1
unsigned short bitColor; //颜色深度
unsigned int zipFormat; //压缩类型
unsigned int realSize; //位图的大小
unsigned int xPels; //位图的水平分辨率
unsigned int yPels; //位图的垂直分辨率
unsigned int colorUse; //位图实际使用的颜色色数
unsigned int colorImportant;//位图显示过程中的重要颜色素
}InfoHead;
int i = 0, j = 0;
BmpHead m_BMPHeader = { 0 };
InfoHead m_BMPInfoHeader = { 0 };
char bfType[2] = { 'B','M' };
int header_size = sizeof(bfType) + sizeof(BmpHead) + sizeof(InfoHead);
unsigned char* rgb24_buffer = NULL;
FILE* fp_rgb24 = NULL;
FILE* fp_bmp = NULL;
if ((fp_rgb24 = fopen(rgb24path, "rb")) == NULL) {
printf("Error: Cannot open input RGB24 file.\n");
return -1;
}
if ((fp_bmp = fopen(bmppath, "wb")) == NULL) {
printf("Error: Cannot open output BMP file.\n");
return -1;
}
rgb24_buffer = (unsigned char*)malloc(width * height * 3);
fread(rgb24_buffer, 1, width * height * 3, fp_rgb24);
//文件的大小。总的RGB+头文件
m_BMPHeader.imageSize = 3 * width * height + header_size;
//位图文件头到数据的偏移量
m_BMPHeader.startPosition = header_size;
m_BMPInfoHeader.Length = sizeof(InfoHead);
m_BMPInfoHeader.width = width;
//BMP存储y轴相反方向(从下到上)的像素数据
m_BMPInfoHeader.height = -height;
//目标设备,1
m_BMPInfoHeader.colorPlane = 1;
//颜色深度
m_BMPInfoHeader.bitColor = 24;
//位图大小
m_BMPInfoHeader.realSize = 3 * width * height;
fwrite(bfType, 1, sizeof(bfType), fp_bmp);
fwrite(&m_BMPHeader, 1, sizeof(m_BMPHeader), fp_bmp);
fwrite(&m_BMPInfoHeader, 1, sizeof(m_BMPInfoHeader), fp_bmp);
//BMP改变RGB的存储顺序
//R->G->B||B->G->R
for (j = 0; j < height; j++) {
for (i = 0; i < width; i++) {
char temp = rgb24_buffer[(j * width + i) * 3 + 2];
rgb24_buffer[(j * width + i) * 3 + 2] = rgb24_buffer[(j * width + i) * 3 + 0];
rgb24_buffer[(j * width + i) * 3 + 0] = temp;
}
}
fwrite(rgb24_buffer, 3 * width * height, 1, fp_bmp);
fclose(fp_rgb24);
fclose(fp_bmp);
free(rgb24_buffer);
printf("Finish generate %s!\n", bmppath);
return 0;
}
int main()
{
rgb24_to_bmp("2.rgb",640,640,"2.bmp");
return 0;
}
封装后的图片可以通过自带的图片播放器播放。