📄 bitmap2sd256.c
字号:
#include "stdio.h"
#include "stdlib.h"
////BMP文件组成
////BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。
//
////BMP文件头
////BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。
////其结构定义如下:
//typedef struct tagBITMAPFILEHEADER
//{
//unsigned short int bfType; // 位图文件的类型,必须为BM
//unsigned long bfSize; // 位图文件的大小,以字节为单位
//unsigned short int bfReserved1; // 位图文件保留字,必须为0
//unsigned short int bfReserved2; // 位图文件保留字,必须为0
//unsigned long bfOffBits; // 位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位
//} BITMAPFILEHEADER;
//
////BMP位图信息头数据用于说明位图的尺寸等信息。
//typedef struct tagBITMAPINFOHEADER
//{
//unsigned long biSize; // 本结构所占用字节数
//long biWidth; // 位图的宽度,以像素为单位
//long biHeight; // 位图的高度,以像素为单位
//unsigned short int biPlanes; // 目标设备的级别,必须为1
//unsigned short int biBitCount; // 每个像素所需的位数,必须是1(双色), 4(16色),8(256色)或24(真彩色)之一
//unsigned long biCompression; // 位图压缩类型,必须是 0(不压缩), 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
//unsigned long biSizeImage; // 位图的大小,以字节为单位
//long biXPelsPerMeter; // 位图水平分辨率,每米像素数
//long biYPelsPerMeter; // 位图垂直分辨率,每米像素数
//unsigned long biClrUsed; // 位图实际使用的颜色表中的颜色数
//unsigned long biClrImportant; // 位图显示过程中重要的颜色数
//} BITMAPINFOHEADER;
//
//
//// 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结
////构,定义一种颜色。RGBQUAD结构的定义如下:
//typedef struct tagRGBQUAD
//{
//unsigned char rgbBlue; // 蓝色的亮度(值范围为0-255)
//unsigned char rgbGreen; // 绿色的亮度(值范围为0-255)
//unsigned char rgbRed; // 红色的亮度(值范围为0-255)
//unsigned char rgbReserved; // 保留,必须为0
//} RGBQUAD;
//
////颜色表中RGBQUAD结构数据的个数有biBitCount来确定:
////当biBitCount=1,4,8时,分别有2,16,256个表项;
////当biBitCount=24时,没有颜色表项。
////位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
//typedef struct tagBITMAPINFO {
//BITMAPINFOHEADER bmiHeader; // 位图信息头
//RGBQUAD bmiColors[1]; // 颜色表
//} BITMAPINFO;
//
////5. 位图数据
//// 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间 是从下到上。
////位图的一个像素值所占的字节数:
////当biBitCount=1时,8个像素占1个字节;
////当biBitCount=4时,2个像素占1个字节;
////当biBitCount=8时,1个像素占1个字节;
////当biBitCount=24时,1个像素占3个字节;
////Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充,
////一个扫描行所占的字节数计算方法:
////DataSizePerLine= (biWidth* biBitCount+31)/8;
////// 一个扫描行所占的字节数
////DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数
////位图数据的大小(不压缩情况下):
////DataSize= DataSizePerLine* biHeight;
//
unsigned char *sd256_bitmap = NULL; //包含前8个字节
unsigned char *sd256_YUV = NULL; //不包含前8个字节,只有调色板和数值索引信息
typedef struct tagBITMAPFILEHEADER
{
unsigned short int bfType;
unsigned long bfSize;
unsigned short int bfReserved1;
unsigned short int bfReserved2;
unsigned long bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER
{
unsigned long biSize;
long biWidth;
long biHeight;
unsigned short int biPlanes;
unsigned short int biBitCount;
unsigned long biCompression;
unsigned long biSizeImage;
long biXPelsPerMeter;
long biYPelsPerMeter;
unsigned long biClrUsed;
unsigned long biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagRGBQUAD
{
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
} RGBQUAD;
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;
/////////////////////////////////////////////////////////////////
// rgb to yuv conversion routines
// rgb 2 yuv:
// Y = 0.257r + 0.504g + 0.098b + 16
// Cb = -0.148r - 0.291g + 0.439b + 128
// Cr = 0.439r + 0.368g + 0.071b + 128
static char rgb2y (char r, char g, char b)
{
long f = 257*(long)r + 504*(long)g + 98*(long)b + 16000;
if (f > 255000)
f = 255000;
f = f / 1000;
return (char)f;
}
static char rgb2u (char r, char g, char b)
{
long f = -148*(long)r - 291*(long)g + 439*(long)b + 128000;
if (f > 255000)
f = 255000;
if (f < 0)
f = 0;
f = f / 1000;
return (char)f;
}
static char rgb2v (char r, char g, char b)
{
long f = 439*(long)r - 368*(long)g - 71*(long)b + 128000;
if (f > 255000)
f = 255000;
if (f < 0)
f = 0;
f = f / 1000;
return (char)f;
}
// end rgb to yuv conversion routines
/////////////////////////////////////////////////////////////////
int ConvertBmpFile (char *BmpFileName, char *HeaderFileName)
{
FILE *f;
FILE *fp;
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
unsigned long LineBytes;
unsigned long ImgSize;
unsigned long i, j, k;
unsigned long NumColors;
unsigned long sd256_bitmap_len;
short int n, buf[20];
char temp[8];
char yvalue;
char uvalue;
char vvalue;
f = fopen (BmpFileName,"rb");
if (f == NULL)
{
printf ("can not open bmp file");
return 0;
}
memset (buf, 0, sizeof (buf));
n = fread (buf, 2, 7, f);
printf ("n = %d\n", n);
bf.bfType = buf[0];
bf.bfSize = (unsigned long) buf[1];
bf.bfReserved1 = buf[3];
bf.bfReserved2 = buf[4];
bf.bfOffBits = (unsigned long) buf[5];
printf ("bf.bfType = %d\n", bf.bfType);
printf ("bf.bfSize = %d\n", bf.bfSize);
printf ("bf.bfReserved1 = %d\n", bf.bfReserved1);
printf ("bf.bfReserved2 = %d\n", bf.bfReserved2);
printf ("bf.bfOffBits = %d\n", bf.bfOffBits);
fseek (f, 14, SEEK_SET);
memset (buf, 0, sizeof (buf));
n = fread (buf, 2, 40, f);
printf ("n = %d\n", n);
bi.biSize = (unsigned long) buf[0];
bi.biWidth = (long) buf[2];
bi.biHeight = (long) buf[4];
bi.biPlanes = buf[6];
bi.biBitCount = buf[7];
bi.biCompression = (unsigned long) buf[8];
bi.biSizeImage = (unsigned long) buf[10];
bi.biXPelsPerMeter = (long) buf[12];
bi.biYPelsPerMeter = (long) buf[14];
bi.biClrUsed = (unsigned long) buf[16];
bi.biClrImportant = (unsigned long) buf[18];
printf ("bi.biSize = %d\n", bi.biSize);
printf ("bi.biWidth = %d\n", bi.biWidth);
printf ("bi.biHeight = %d\n", bi.biHeight);
printf ("bi.biPlanes = %d\n", bi.biPlanes);
printf ("bi.biBitCount = %d\n", bi.biBitCount);
printf ("bi.biCompression = %d\n", bi.biCompression);
printf ("bi.biSizeImage = %d\n", bi.biSizeImage);
printf ("bi.biXPelsPerMeter = %d\n", bi.biXPelsPerMeter);
printf ("bi.biYPelsPerMeter = %d\n", bi.biYPelsPerMeter);
printf ("bi.biClrUsed = %d\n", bi.biClrUsed);
printf ("bi.biClrImportant = %d\n", bi.biClrImportant);
LineBytes = (unsigned long) bi.biWidth * bi.biBitCount;
ImgSize = (unsigned long) LineBytes * bi.biHeight;
printf ("ImgSize = %d\n", ImgSize);
if(bi.biClrUsed != 0)
{
NumColors = (unsigned long) bi.biClrUsed;
}
else
{
switch(bi.biBitCount)
{
case 1:
NumColors=2;
break;
case 4:
NumColors=16;
break;
case 8:
NumColors=256;
break;
case 24:
NumColors=0;
break;
default:
fclose(f);
return 1;
}
}
if(bf.bfOffBits != (unsigned long) (NumColors * sizeof(RGBQUAD) + 14+40))
{
printf ("Invalid color numbers!\n");
fclose(f);
return 1;
}
sd256_bitmap_len = (unsigned long)(NumColors*sizeof(RGBQUAD))+ImgSize;
printf ("sd256_bitmap_len = %d\n", sd256_bitmap_len);
temp[0] = 0x3e;
temp[1] = 0x00;
temp[2] = (char) (sd256_bitmap_len & 0xff00);
temp[3] = (char) (sd256_bitmap_len & 0x00ff);
temp[4] = (char) (bi.biWidth & 0xff00);
temp[5] = (char) (bi.biWidth & 0x00ff);
temp[6] = (char) (bi.biHeight & 0xff00);
temp[7] = (char) (bi.biHeight & 0x00ff);
if((sd256_bitmap = (char *) malloc (sd256_bitmap_len))==NULL)
{
printf ("Error alloc memory!\n");
fclose(f);
free (sd256_bitmap);
return 1;
}
if((sd256_YUV = (char *) malloc (sd256_bitmap_len))==NULL)
{
printf ("Error alloc memory!\n");
fclose(f);
free (sd256_bitmap);
return 1;
}
fseek (f, 14+40, SEEK_SET);
n = fread (sd256_bitmap, 1, sd256_bitmap_len, f);
printf ("n = %d\n", n);
fclose (f);
fp = fopen (HeaderFileName, "w+t");
for (i=0; i<1024; i+=4)
{
// yvalue = rgb2y (sd256_bitmap[i+2], sd256_bitmap[i+1], sd256_bitmap[i]);
// uvalue = rgb2u (sd256_bitmap[i+2], sd256_bitmap[i+1], sd256_bitmap[i]);
// vvalue = rgb2v (sd256_bitmap[i+2], sd256_bitmap[i+1], sd256_bitmap[i]);
// sd256_YUV[i] = 0xff;
// sd256_YUV[i+1] = yvalue;
// sd256_YUV[i+2] = uvalue;
// sd256_YUV[i+3] = vvalue;
sd256_YUV[i] = 0xff; //保留位
sd256_YUV[i+1] = rgb2y (sd256_bitmap[i+2]/*r*/, sd256_bitmap[i+1]/*g*/, sd256_bitmap[i]/*b*/);
sd256_YUV[i+2] = rgb2u (sd256_bitmap[i+2], sd256_bitmap[i+1], sd256_bitmap[i]);
sd256_YUV[i+3] = rgb2v (sd256_bitmap[i+2], sd256_bitmap[i+1], sd256_bitmap[i]);
}
// j=1024;
// for (i=n; i>1024; i--)
// {
// sd256_YUV[j] = sd256_bitmap[i];
// j++;
// }
k = 1024;
for (i=bi.biHeight; i>0; i--)
{
for (j=0; j<bi.biWidth; j++)
{
sd256_YUV[k] = sd256_bitmap[1024+ (i-1) * bi.biWidth + j];
k++;
}
}
fputs ( "unsigned char bitmap[] = {", fp);
fprintf(fp, "\n");
for (i=0; i<8; i++)
{
if (i == 4)
fprintf(fp, "\n");
if (temp[i]<=0x0f)
fprintf(fp, "0x0%1x, ", temp[i]);
else
fprintf(fp, "0x%2x, ", temp[i]);
}
fprintf(fp, "\n");
for (i=0; i<n; i++)
{
if (i < 256*4 && i % 4 == 0)
fprintf(fp, "\n");
else if (i >= 256*4 && i % 8 == 0 )
fprintf(fp, "\n");
if (i == 256*4)
fprintf(fp, "\n");
if (sd256_YUV[i]<=0x0f)
fprintf(fp, "0x0%1x, ", sd256_YUV[i]);
else
fprintf(fp, "0x%2x, ", sd256_YUV[i]);
}
fprintf(fp, "\n");
fputc('}', fp);
fputc(';', fp);
fclose(fp);
free (sd256_bitmap);
free (sd256_YUV);
return 0;
}
int main (int argc, char *argv[])
{
int ret;
if (argc <3) {
printf("%s <input bmp file> <output header file>\n", argv[0]);
exit(0);
}
printf("Input file: %s\n", argv[1]);
printf("Output file: %s\n", argv[2]);
ret = ConvertBmpFile (argv[1], argv[2]);
if (ret == 0)
{
printf ("Convert success !\n");
return 0;
}
else
{
printf ("Convert fail !\n");
return 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -