/*
* ttt.cpp
*
* Created on: 2012-12-5
* Author: xy
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*
part one,14 bit
*/
#pragma pack(2) //以2个字节对齐
struct head {
short int bfType; //位图类型
long int bfsize; //位图文件大小
short int freserved1; //必须为0
short int freserved2; //必须为0
long int bfoffbits; //第54个开始
} head;
/*
part,two, 40 bit
*/
struct info {
long int bisize; //本结构站用的字节数 40
long biwidth; //位图的宽度
long biheight; //位图的高度
short int biplanes; //目标设备的级别
short int BIBITCOUNT; //每个象素所需的位数
long int bigcompression; //位图压缩类型
long int bisizeimage; //位图的大小
long bixpelspermeter;
long biypelspermeter;
long int biclrused;
long int biclrimportant;
} info;
#pragma pack()
void init_bmp()
{
info.bisize = 0x28 ;// 本结构的大小40个字节
info.biwidth = 200; //位图宽
info.biheight= 20; //位图高 要修改
info.biplanes = 0;
info.BIBITCOUNT = 32 ;// 位图的色深 32是要字节对齐
info.bigcompression = 0 ;// 表示不压缩
info.bixpelspermeter = 200*20*4; //位图数据
info.bixpelspermeter=0;
info.biypelspermeter=0;
info.biclrused = 0;
info.biclrimportant = 0;
head.bfType=0x4d42;//ASICC bm
head.bfsize = 200*20*4+56; //位图数据 + 数据头
head.freserved1=0;
head.freserved2=0;
head.bfoffbits=0x36;//54
}
/*****************************************************
* 功能:读字库
* 参数:character 传入字符 character_size 字符gb2312码的个数 buf 传出字符在字库中的值 buf_size buf的字节数
* 补充:character传入的字符一定要是gb2312,一定不能是utf-8的。
* **************************************************/
int read_data_from_hzk(unsigned char *buf,unsigned int buf_size, char *character,unsigned int character_size)
{
unsigned char qh,wh;//区 位
int ret;
unsigned long offset;//字库中偏移
unsigned int i;
FILE *HZK;
if(strlen(character)/2!=character_size||buf_size/32!=character_size)//检查是不是gb2312的码
{
printf("the character is wrong 2 \n");
return -1;
}
for(i=0;i<character_size; i++)
{
unsigned char *p=(unsigned char *)(character+i*2); //两个字节,也就是一个字符偏移一下
if(*p<0xa0||*(p+1)<0xa0) //检查是不是gb2312的码
{
printf("the character is wrong 1 \n");
return -1;
}
qh=p[0]- 0xa0;;
wh=p[1]- 0xa0;;
offset = (94*(qh-1)+(wh-1))*32;
if((HZK=fopen("HZK16","r"))==NULL)
{
printf("Can't Open hzk16\n");
return -1;
}
ret=fseek(HZK,offset,SEEK_SET);
if(ret<0)
{
printf("error in fseek\n");
return -1;
}
ret=fread( buf+i*32,32,1,HZK); //读的时候,每个16*16字符点32个字节
if(ret!=1)
{
printf("error in fread,the size is %d\n",ret);
return -1;
}
}
fclose(HZK);
return 0;
}
/*******************************************************
* 功能:在位图中写字,就是把库中读的内容写到位图中
* 参数:character_buf 从字库中读出的字符存在的位置 character_buf_size 字符占用的空间 p 位图数据 p_size位图数据占用的空间
*******************************************************/
void write_BMP(unsigned char *character_buf,unsigned int character_buf_size ,unsigned char *p,unsigned int p_size)
{
//fseek(fp,54,SEEK_SET);//把文件头偏移过去
printf("characters_buf_size:%d\n",character_buf_size);
unsigned int i,j,k,size;
unsigned char *cbuf;
for(size=0;size<character_buf_size/32; size++)
{
cbuf=character_buf+size*32; //一个字符战用32个字节
for(j=0;j<16;j++)
{
for(i=0;i<2;i++)
{
for(k=0;k<8;k++)
{
if(((cbuf[j*2+i]>>(7-k))&0x1)!=0)
{
printf("x");
//*(int *)(p+(200*(2+j)+i*8+k)*4)=0xff000000;//显示在左,左右反的,坐标系统理解不正确
//*(int *)(p+200*18*4-(200*(2+j)+i*8+k)*4)=0xff000000;//显示在右边,左右反的,坐标系统理解不正确
*(int *)(p+200*(16+1/*1 是(20-16)/2-1 就是要把字放在格子的中间*/)*4-j*200*4+i*8*4+k*4+(16*size)*4)=0xff00FF00;
//指针是unsigned char ,要这样写,这个就可以用了, 第一个字size是0第二个字size是1 16是字库的边长 200是bmp的长
}
else
{
//*(p+(200*(2+j)+i*8+j)*4)=128;
printf(" ");
}
}
}
printf("\n");
}
printf("\nsize:%d\n",size);
}
}
int main()
{
init_bmp();
FILE *fp = fopen("11.bmp","w");
fwrite(&head, 1, sizeof(struct head),fp);
fwrite(&info, 1, sizeof(struct info),fp);
unsigned char *p= (unsigned char *)malloc(200*20*4); //分配一个bmp数据的内存
memset(p, 0xff, 200*20*4); //做成白底的
unsigned char *buf;//存放从字库中读出来的内容
char character[]="你好";
unsigned int character_size=strlen(character)/2;//字库是gb2312的,一个字占两个字节
printf("character size:%d\n",character_size);
unsigned buf_size=character_size*32;
buf=(unsigned char *)malloc(buf_size); //一个16*16的点阵占用32个字节
if(read_data_from_hzk(buf , buf_size, character,character_size)<0)
{
printf("read error\n");
exit(1);
}
write_BMP(buf,buf_size,p,1);
fwrite(p,1, 200*20*4,fp);
fclose(fp);
return 0;
}
创建一个200*20的bmp,并在bmp中写汉字