首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

继续散分,继续提问关于BMP图片生成有关问题

2013-07-08 
继续散分,继续提问关于BMP图片生成问题。由于问题描述的不清楚,导致上一个问题,结贴的不是很完美,故重新发

继续散分,继续提问关于BMP图片生成问题。
由于问题描述的不清楚,导致上一个问题,结贴的不是很完美,故重新发帖,顺便散分。
目的:希望把汉字“中”生成一个BMP 图片。
现状:完成了BMP图片生成,但是汉字没写上去(加载了HZF16字库,不确定这是一种正确的方法,主要是在图片上打印出一个汉字,不清楚是一个什么样的流程,话不多说,上代码,求解)。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef long BOOL;
typedef long LONG;
typedef unsigned char BYTE;
typedef unsigned long DWORD;
typedef unsigned short WORD;
#include <pshpack2.h>
typedef struct {
        WORD    bfType;
        DWORD   bfSize;
        WORD    bfReserved1;
        WORD    bfReserved2;
        DWORD   bfOffBits;
} BMPFILEHEADER_T;
struct BMPFILEHEADER_S{
        WORD    bfType;
        DWORD   bfSize;
        WORD    bfReserved1;
        WORD    bfReserved2;
        DWORD   bfOffBits;
};
typedef struct{
        DWORD      biSize;
        LONG       biWidth;
        LONG       biHeight;
        WORD       biPlanes;
        WORD       biBitCount;
        DWORD      biCompression;
        DWORD      biSizeImage;
        LONG       biXPelsPerMeter;
        LONG       biYPelsPerMeter;
        DWORD      biClrUsed;
        DWORD      biClrImportant;
} BMPINFOHEADER_T;

void Snapshot( BYTE * pData, int width, int height,  char * filename )
{
       int size = width*height*3; // 每个像素点3个字节


       // 位图第一部分,文件信息
       BMPFILEHEADER_T bfh;
   BMPINFOHEADER_T bih;
       FILE *fp;

       bfh.bfType = 0x4d42;  //bm
       bfh.bfSize = size  // data size
              + sizeof( BMPFILEHEADER_T ) // first section size
              + sizeof( BMPINFOHEADER_T ) // second section size
              ;
       bfh.bfReserved1 = 0; // reserved 
       bfh.bfReserved2 = 0; // reserved
       bfh.bfOffBits = bfh.bfSize - size;
 
       // 位图第二部分,数据信息

       bih.biSize = sizeof(BMPINFOHEADER_T);
       bih.biWidth = width;
       bih.biHeight = height;
       bih.biPlanes = 1;
       bih.biBitCount = 24;
       bih.biCompression = 0;
       bih.biSizeImage = size;
       bih.biXPelsPerMeter = 0;
       bih.biYPelsPerMeter = 0;
       bih.biClrUsed = 0;
       bih.biClrImportant = 0;      
        
fp = fopen( filename,"wb");
       if( !fp ) return;
       fwrite( &bfh, 1, sizeof(BMPFILEHEADER_T), fp );
       fwrite( &bih, 1, sizeof(BMPINFOHEADER_T), fp );
       fwrite( pData, 1, size, fp );

       fclose(fp);
}
/**********************************
* 得到汉字字符的字模信息,存入数组
* 参数:
*   *c:要得到字模信息的字符指针
*   buffer[]:存储字模信息的数组
* 无返回值
***********************************/


void getHzKCode(char *c,char buff[])
{
unsigned char qh,wh;
unsigned long offset;
    FILE *HZK;
/*打开字库文件hzk16*/
if((HZK=fopen("E:\\fonts\\HZK16","rb"))==NULL){
       printf("Can't open haz16,Please add it?");
       getchar();
       exit(0);
}
/*区码=内码(高字节)-160  位码=内码(低字节)-160*/
    qh     = *(c) -0xa0; /*10进制的160等于16进制的A0*/
    wh     = *(c+1) -0xa0; /*获得区码与位码*/
    offset = (94*(qh-1)+(wh-1))*32L;/*计算该汉字在字库中偏移量*/
    fseek(HZK,offset,SEEK_SET); /*将文件指针移动到偏移量的位置*/
    fread(buff,32,1,HZK); /*从偏移量的位置读取32个字节*/
    printf("qh:%d,wh:%d,offset:%ld\n\r",qh,wh,offset);
}
void main() 
{
unsigned char *HzkC  = "中";
char *hzk;
char buffer2[32]; /*存储中文字模信息*/
unsigned char HzkC1 = 0xff;
    unsigned char HzkC2 = 0x00;
       int i, j,k;
       struct {
              BYTE b;
              BYTE g;
              BYTE r;
       } pRGB[240][320];  // 定义位图数据
       memset( pRGB, 0, sizeof(pRGB) ); // 设置背景为黑色

   /*输出中文字符*/
       getHzKCode(HzkC,buffer2);
       hzk = buffer2;

  for(i=0;i<16;i++) /*16x16点阵汉字,一共有16行*/
{
for(j=0;j<2;j++) /*横向有2个字节,循环判断每个字节的*/
for(k=0;k<8;k++) /*每个字节有8位,循环判断每位是否为1*/
if(hzk[i*2+j]&(0x80>>k)) /*测试当前位是否为1*/
pRGB[i][j].r = HzkC1; /*为1的显示为字符c1*/    
else 
pRGB[i][j].r = HzkC2; /*为0的显示为字符c2*/
}
   printf("begin\n");
   getchar();
       // 生成BMP图片
       Snapshot( ( BYTE*)pRGB, 240, 320, "c:\\rgb.bmp" );

   printf("end\n");
}



122-130行 这段是输出一个“中”字的点阵,不确定这种方法是否可行。不过确实没有办法了,


[解决办法]
好的 下班接分
[解决办法]
直接用 GDI 来写字多简单!


#include <windows.h>

BOOL  SaveBmp(HBITMAP hBitmap, char* FileName);

int main()
{
HDC hDC = CreateCompatibleDC(GetDC(NULL));
HBITMAP hBitMap = CreateCompatibleBitmap(hDC, 120, 120);
SelectObject(hDC, hBitMap);
TextOut(hDC, 10, 10, "中文", 4);

SaveBmp(hBitMap, "D:\\test.bmp");
}


其中的 SaveBmp 是网上随便找的一个函数:



BOOL  SaveBmp(HBITMAP hBitmap, char* FileName)         
{         
HDC     hDC;         
//当前分辨率下每象素所占字节数         
int     iBits;         
//位图中每象素所占字节数         
WORD     wBitCount;         
//定义调色板大小,     位图中像素字节大小     ,位图文件大小     ,     写入文件字节数             
DWORD     dwPaletteSize=0,   dwBmBitsSize=0,   dwDIBSize=0,   dwWritten=0;             
//位图属性结构             
BITMAP     Bitmap;                 
//位图文件头结构         
BITMAPFILEHEADER     bmfHdr;                 
//位图信息头结构             
BITMAPINFOHEADER     bi;                 


//指向位图信息头结构                 
LPBITMAPINFOHEADER     lpbi;                 
//定义文件,分配内存句柄,调色板句柄             
HANDLE     fh,   hDib,   hPal,hOldPal=NULL;             

//计算位图文件每个像素所占字节数             
hDC  = CreateDC("DISPLAY",   NULL,   NULL,   NULL);         
iBits  = GetDeviceCaps(hDC,   BITSPIXEL)     *     GetDeviceCaps(hDC,   PLANES);             
DeleteDC(hDC);             
if(iBits <=  1)                                                   
wBitCount = 1;             
else  if(iBits <=  4)                               
wBitCount  = 4;             
else if(iBits <=  8)                               
wBitCount  = 8;             
else                                                                                                                               


wBitCount  = 24;             

GetObject(hBitmap,   sizeof(Bitmap),   (LPSTR)&Bitmap);         
bi.biSize= sizeof(BITMAPINFOHEADER);         
bi.biWidth = Bitmap.bmWidth;         
bi.biHeight =  Bitmap.bmHeight;         
bi.biPlanes =  1;         
bi.biBitCount = wBitCount;         
bi.biCompression= BI_RGB;         
bi.biSizeImage=0;         
bi.biXPelsPerMeter = 0;         
bi.biYPelsPerMeter = 0;         
bi.biClrImportant = 0;         
bi.biClrUsed =  0;         

dwBmBitsSize  = ((Bitmap.bmWidth *wBitCount+31) / 32)*4* Bitmap.bmHeight;         

//为位图内容分配内存             
hDib  = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));             
lpbi  = (LPBITMAPINFOHEADER)GlobalLock(hDib);             
*lpbi  = bi;             

//     处理调色板                 
hPal  = GetStockObject(DEFAULT_PALETTE);             
if (hPal)             
{             
hDC  = ::GetDC(NULL);             
hOldPal = ::SelectPalette(hDC,(HPALETTE)hPal, FALSE);             
RealizePalette(hDC);             
}         

//     获取该调色板下新的像素值             


GetDIBits(hDC,hBitmap, 0,(UINT)Bitmap.bmHeight,  
(LPSTR)lpbi+ sizeof(BITMAPINFOHEADER)+dwPaletteSize,   
(BITMAPINFO *)lpbi, DIB_RGB_COLORS);             

//恢复调色板                 
if (hOldPal)             
{             
::SelectPalette(hDC,   (HPALETTE)hOldPal,   TRUE);             
RealizePalette(hDC);             
::ReleaseDC(NULL,   hDC);             
}             

//创建位图文件                 
fh  = CreateFile(FileName,   GENERIC_WRITE,0,   NULL,   CREATE_ALWAYS,           
FILE_ATTRIBUTE_NORMAL 
[解决办法]
 FILE_FLAG_SEQUENTIAL_SCAN,   NULL);             

if (fh     ==  INVALID_HANDLE_VALUE)         return     FALSE;             

//     设置位图文件头             
bmfHdr.bfType  = 0x4D42;     //     "BM"             
dwDIBSize  = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize;                 
bmfHdr.bfSize  = dwDIBSize;             
bmfHdr.bfReserved1  = 0;             
bmfHdr.bfReserved2  = 0;             
bmfHdr.bfOffBits  = (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwPaletteSize;             


//     写入位图文件头             
WriteFile(fh,   (LPSTR)&bmfHdr,   sizeof(BITMAPFILEHEADER),   &dwWritten,   NULL);             
//     写入位图文件其余内容             
WriteFile(fh,   (LPSTR)lpbi,   dwDIBSize,   &dwWritten,   NULL);             
//清除                 
GlobalUnlock(hDib);             
GlobalFree(hDib);             
CloseHandle(fh);             

return     TRUE;         
}  


[解决办法]
 for(i=0;i<16;i++) /*16x16点阵汉字,一共有16行*/
        {
            for(j=0;j<2;j++) /*横向有2个字节,循环判断每个字节的*/
                for(k=0;k<8;k++) /*每个字节有8位,循环判断每位是否为1*/
                    if(hzk[i*2+j]&(0x80>>k)) /*测试当前位是否为1*/
                        pRGB[i][j].r = HzkC1; /*为1的显示为字符c1*/                        
                    else 
                        pRGB[i][j].r = HzkC2; /*为0的显示为字符c2*/
        }

核心部分有问题,你的思路是在位图的左上角打印一个方块汉字,但是你的pRGB[i][j]中的J的活动范围只有0和1 ,需要修改   改成pRGB[i][j*8+k]   没有运行,只是眼看的有毛病。  如果不是者的问题  那就是字库点阵数据没有上来,打印一下确保以下,再就是 为判断有可能有问题,但是那种代码我是100个不愿意研究啊,祝你好运。
[解决办法]
楼主在不在,那样改好使么???
------解决方案--------------------


仅供参考

#include <mem.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <graphics.h>
const unsigned char bit[8]={128,64,32,16,8,4,2,1};
//--------------------
void dis(xoff,code)
    unsigned int xoff,code;
{
    unsigned char *buffer;
    FILE *hzk;
    unsigned long offset;
    unsigned int q,w;
    int x,y,width;

    buffer=calloc(32,1);
    if ((code&0xFF00)!=0) {
        w=(code&0x00FF)-0xA1;
        q=((code>>8)&0x00FF)-0xA1;
        offset=q*0x5E+w;
        offset*=32;
        if ((hzk=fopen("HZK16","rb"))==NULL) {
            closegraph();
            printf("Can not open HZK16\r\n");
            exit(1);
        }
        fseek(hzk,offset,SEEK_SET);
        fread(buffer,1,32,hzk);
        fclose(hzk);
        width=2;
    }
    else {
        if ((hzk=fopen("ASC16","rb"))==NULL) {
            closegraph();
            printf("Can not open ASC16\r\n");
            exit(1);
        }
        offset=code*16;
        fseek(hzk,offset,SEEK_SET);
        fread(buffer,1,16,hzk);
        fclose(hzk);
        width=1;
    }
    for (y=0;y<16;y++) for (x=0;x<8*width;x++) {
        if (buffer[y*width+x/8]&bit[x%8]) putpixel(xoff+x,y,15);


    }
    free(buffer);
}
//--------------------
void display(p)
    unsigned char *p;
{

  int i;
  unsigned int qw;

  i=0;
  while (1) {
    if (p[i]==0x0D
[解决办法]
p[i]==0x1A) break;
if (p[i]>0xA0) {
qw=((unsigned int)p[i]<<8)
[解决办法]
((unsigned int)p[i+1]&0x00FF);
dis(8*i,qw);
i+=2;
}
else {
qw=(unsigned int)p[i]&0x00FF;
dis(8*i,qw);
i++;
}
  }

}
//--------------------
void main()
{
int gdriver = DETECT, gmode, errorcode;
long fl;
FILE *hz;
unsigned char *p;

initgraph(&gdriver, &gmode, "c:\\borlandc\\bgi");
errorcode = graphresult();
if (errorcode != grOk) {
   printf("Graphics error: %s\n", grapherrormsg(errorcode));
   exit(1);
}
hz=fopen("hz","rb");
fseek(hz,0,SEEK_END);
fl=ftell(hz);
p=calloc((int)fl,sizeof(unsigned char));
rewind(hz);
fread(p,1,(int)fl,hz);
fclose(hz);
display(p);
free(p);
getch();
closegraph();
}


[解决办法]
C源代码:12x12汉字点阵库(支持GBK)及其处理
http://download.csdn.net/detail/zhao4zhong1/2180241

热点排行