📄 loadbmp.c
字号:
/*************************************************** Copyright(C), 2008 , JUST File name: loadbmp.c Author: StevenZ Version: 1.0 Date: 08/09/06 Description: loadbmp.h文件的实现 利用FrameBuffer做的图片载入和定点显示 ps:只能为24位色.bmp无压缩图片 History: 08/08/31 完成初步功能:清屏,定位(根据屏幕位置)显示图片 08/09/03 添加根据触摸屏所得位置显示图片 08/09/06 小小修正 08/09/24 替换逐像素画图,提高显示速度 ***************************************************/#include "./inc/loadbmp.h"#include "./inc/fbapi.h"int USE_TMS=1; //1:使用TMS(透明色),0:不使用TMS/*装入图片,填充图片结构体*/int LoadBitmapFromFile(BITMAP *pBitmap,const char *filename){ int bm_fd; unsigned int t_uint; //long t_long; int t_int; char temp[8]; /*pBitmap->bmName=(char *)malloc(sizeof(filename)+1); if(pBitmap->bmName==NULL) return -1;*/ strcpy(pBitmap->bmName,filename); bm_fd=open(pBitmap->bmName,O_RDWR); if(bm_fd<=0) return -2; /*文件标识,2bytes*/ read(bm_fd,temp,2); pBitmap->bmBF.bfType=(temp[1]<<8)|temp[0]; /*整个文件大小,4bytes*/ read(bm_fd,temp,4); pBitmap->bmBF.bfSize=(temp[3]<<24)|(temp[2]<<16)|(temp[1]<<8)|temp[0]; /*保留,4bytes,必为0*/ read(bm_fd,temp,4); t_uint=(temp[3]<<24)|(temp[2]<<16)|(temp[1]<<8)|temp[0]; if(t_uint!=0) return -3; pBitmap->bmBF.bfReserved1=t_uint; pBitmap->bmBF.bfReserved2=t_uint; /*从文件开始到位图数据的偏移,4bytes*/ read(bm_fd,temp,4); pBitmap->bmBF.bfOffBits=(temp[3]<<24)|(temp[2]<<16)|(temp[1]<<8)|temp[0]; /*位图文件头长度,4bytes*/ read(bm_fd,temp,4); pBitmap->bmBMI.bmiHeader.biSize=(temp[3]<<24)|(temp[2]<<16)|(temp[1]<<8)|temp[0]; /*宽度,像素为单位,4bytes*/ read(bm_fd,temp,4); pBitmap->bmBMI.bmiHeader.biWidth=(temp[3]<<24)|(temp[2]<<16)|(temp[1]<<8)|temp[0]; /*高度,像素为单位,4bytes*/ read(bm_fd,temp,4); pBitmap->bmBMI.bmiHeader.biHeight=(temp[3]<<24)|(temp[2]<<16)|(temp[1]<<8)|temp[0]; /*位面数,一般为1,2bytes*/ read(bm_fd,temp,2); pBitmap->bmBMI.bmiHeader.biPlanes=(temp[1]<<8)|temp[0]; /*每个像素位数,2bytes*/ read(bm_fd,temp,2); pBitmap->bmBMI.bmiHeader.biBitCount=(temp[1]<<8)|temp[0]; /*压缩说明,4bytes*/ read(bm_fd,temp,4); pBitmap->bmBMI.bmiHeader.biCompression=(temp[3]<<24)|(temp[2]<<16)|(temp[1]<<8)|temp[0]; /*用字节数表示的位图数据大小,4bytes*/ read(bm_fd,temp,4); pBitmap->bmBMI.bmiHeader.biSizeImage=(temp[3]<<24)|(temp[2]<<16)|(temp[1]<<8)|temp[0]; /*用像素每米表示的水平分辨率,4bytes*/ read(bm_fd,temp,4); pBitmap->bmBMI.bmiHeader.biXPelsPerMeter=(temp[3]<<24)|(temp[2]<<16)|(temp[1]<<8)|temp[0]; /*用像素每米表示的垂直分辨率,4bytes*/ read(bm_fd,temp,4); pBitmap->bmBMI.bmiHeader.biXPelsPerMeter=(temp[3]<<24)|(temp[2]<<16)|(temp[1]<<8)|temp[0]; /*位图使用的颜色数,如256色,4bytes*/ read(bm_fd,temp,4); pBitmap->bmBMI.bmiHeader.biClrUsed=(temp[3]<<24)|(temp[2]<<16)|(temp[1]<<8)|temp[0]; /*重要颜色,4bytes*/ read(bm_fd,temp,4); pBitmap->bmBMI.bmiHeader.biClrImportant=(temp[3]<<24)|(temp[2]<<16)|(temp[1]<<8)|temp[0]; switch(pBitmap->bmBMI.bmiHeader.biBitCount) { case 24: break; case 1: case 2: case 4: case 8: case 16: case 32: printf("it's not a 24bit bmp,colors bit error!!\n"); return -3; } close(bm_fd); return 0;}#define LoadBitmap LoadBitmapFromFile/*卸载装入的图片*/void UnLoadBitmap(BITMAP *pBitmap){ //if(pBitmap->bmName) // free(pBitmap->bmName); }/*打印显示位图信息*/void ShowBitmapInfo(BITMAP *pBitmap){ //int i; DPRINTF("file %s information:\n",pBitmap->bmName); DPRINTF("bmBF.bfType=%s.\n",(char *)&(pBitmap->bmBF.bfType)); DPRINTF("file size is %d bytes.\n",pBitmap->bmBF.bfSize); DPRINTF("fbmBF.bfReserved1=%d.\n",pBitmap->bmBF.bfReserved1); DPRINTF("fbmBF.bfReserved2=%d.\n",pBitmap->bmBF.bfReserved2); DPRINTF("fbmBF.bfOffBits=%d.\n",pBitmap->bmBF.bfOffBits); DPRINTF("bmBMI.bmiHeader.biSize=%d.\n",pBitmap->bmBMI.bmiHeader.biSize); DPRINTF("bmBMI.bmiHeader.biWidth=%d.\n",pBitmap->bmBMI.bmiHeader.biWidth); DPRINTF("bmBMI.bmiHeader.biHeight=%d.\n",pBitmap->bmBMI.bmiHeader.biHeight); DPRINTF("bmBMI.bmiHeader.biPlanes=%d.\n",pBitmap->bmBMI.bmiHeader.biPlanes); DPRINTF("bmBMI.bmiHeader.biBitCount=%d.\n",pBitmap->bmBMI.bmiHeader.biBitCount); DPRINTF("bmBMI.bmiHeader.biCompression=%d.\n",pBitmap->bmBMI.bmiHeader.biCompression); DPRINTF("bmBMI.bmiHeader.biSizeImage=%d.\n",pBitmap->bmBMI.bmiHeader.biSizeImage); DPRINTF("bmBMI.bmiHeader.biXPelsPerMeter=%d.\n",pBitmap->bmBMI.bmiHeader.biXPelsPerMeter); DPRINTF("bmBMI.bmiHeader.biYPelsPerMeter=%d.\n",pBitmap->bmBMI.bmiHeader.biYPelsPerMeter); DPRINTF("bmBMI.bmiHeader.biClrUsed=%d.\n",pBitmap->bmBMI.bmiHeader.biClrUsed); DPRINTF("bmBMI.bmiHeader.biClrImportant=%d.\n",pBitmap->bmBMI.bmiHeader.biClrImportant); }/*在(fbx,fby)处显示图片(整内存)*/int ShowBitmapOnLCD(int fbx,int fby,PFBDEV pFbdev,BITMAP *pBitmap){ int i,k,x,y,line_len; unsigned int w,h; FILE *bm_fp; unsigned int high,low,data_len; short int color; unsigned char r,g,b; unsigned char *pdata_buf,*pb; line_len=pFbdev->fb_fix.line_length; bm_fp=fopen(pBitmap->bmName,"r"); if(bm_fp==NULL) { printf("can't open file %s!\n",pBitmap->bmName); return -1; } data_len=pBitmap->bmBMI.bmiHeader.biSizeImage; pdata_buf=(char *)malloc(data_len); if(pdata_buf==NULL) { printf("mem error!\n"); return -2; } fseek(bm_fp,pBitmap->bmBF.bfOffBits,SEEK_SET); i=fread(pdata_buf,1,data_len,bm_fp); DPRINTF("fread=%d\n",i); fclose(bm_fp); w=pBitmap->bmBMI.bmiHeader.biWidth; h=pBitmap->bmBMI.bmiHeader.biHeight; DPRINTF("w=%d,h=%d\n",w,h); /*由于行扫描时要DWORD对齐,所以要转换w*3的值 公式为:((width*biBitCount+31)>>5)<<2*/ w=((w*24+31)>>5)<<2; DPRINTF("fix_w=%d\n",w); pb=(char *)malloc(640*480*2); if(w!=640||h!=480) { DPRINTF("mem fb\n"); memcpy(pb,(void *)(pFbdev->fb_mem+pFbdev->fb_mem_offset),640*480*2); } k=0; for(y=0;y<pBitmap->bmBMI.bmiHeader.biHeight;y++) { for(x=0;x<pBitmap->bmBMI.bmiHeader.biWidth;x++) { /*读出的数据左下角为实际图片的(0,0)像素点,通过以下公式可以 *用i来找到(x,y)所对应的数据 */ i=h*w-(w-x*3)-y*w; r=(pdata_buf[i+2]&0xF8); g=(pdata_buf[i+1]&0xFC); b=(pdata_buf[i]&0xF8); high=r|(g>>5); low=(g<<3)|(b>>3); color=(high<<8)|low; if((fbx+x<640)&&(fby+y<480)) { if(USE_TMS==0||color!=TMS) { pb[line_len*(fby+y)+(fbx+x)*2]=low; pb[line_len*(fby+y)+(fbx+x)*2+1]=high; } } } } memcpy((void *)(pFbdev->fb_mem+pFbdev->fb_mem_offset),pb,640*480*2); free(pdata_buf); free(pb); return 0;}/*在(fbx,fby)处显示图片(逐像素)*//* int ShowBitmapOnLCD(int fbx,int fby,PFBDEV pFbdev,BITMAP *pBitmap){ int i,x,y,line_len; unsigned int w,h; FILE *bm_fp; unsigned int high,low,data_len; short int color; unsigned char r,g,b; unsigned char *pdata_buf; line_len=pFbdev->fb_fix.line_length; bm_fp=fopen(pBitmap->bmName,"r"); if(bm_fp==NULL) { printf("can't open file %s!\n",pBitmap->bmName); return -1; } data_len=pBitmap->bmBMI.bmiHeader.biSizeImage; pdata_buf=(unsigned char *)malloc(data_len); if(pdata_buf==NULL) { printf("mem error!\n"); return -2; } fseek(bm_fp,pBitmap->bmBF.bfOffBits,SEEK_SET); i=fread(pdata_buf,1,data_len,bm_fp); DPRINTF("fread=%d\n",i); fclose(bm_fp); w=pBitmap->bmBMI.bmiHeader.biWidth; h=pBitmap->bmBMI.bmiHeader.biHeight; DPRINTF("w=%d,h=%d\n",w,h); //由于行扫描时要DWORD对齐,所以要转换w*3的值 //公式为:((width*biBitCount+31)>>5)<<2 w=((w*24+31)>>5)<<2; DPRINTF("fix_w=%d\n",w); for(y=0;y<pBitmap->bmBMI.bmiHeader.biHeight;y++) { for(x=0;x<pBitmap->bmBMI.bmiHeader.biWidth;x++) { //读出的数据左下角为实际图片的(0,0)像素点,通过以下公式可以 //用i来找到(x,y)所对应的数据 i=h*w-(w-x*3)-y*w; r=(pdata_buf[i+2]&0xF8); g=(pdata_buf[i+1]&0xFC); b=(pdata_buf[i]&0xF8); high=r|(g>>5); low=(g<<3)|(b>>3); color=(high<<8)|low; if(y==0&&x==0) DPRINTF("color=0x%x\n",color); if((fbx+x<640)&&(fby+y<480)) { if(USE_TMS==0||color!=TMS) { fb_memset((void *)(pFbdev->fb_mem+pFbdev->fb_mem_offset +line_len*(fby+y)+(fbx+x)*2),low,1); fb_memset((void *)(pFbdev->fb_mem+pFbdev->fb_mem_offset +line_len*(fby+y)+(fbx+x)*2+1),high,1); } } } } free(pdata_buf); return 0;}*//*fbx,fby图片坐上角在屏幕上位置**fbx:0-639**fby:0-479*/int ShowBitmap(int fbx,int fby,char *file_name)
{
FBDEV fbdev; BITMAP mybmp; LoadBitmap(&mybmp,file_name); //ShowBitmapInfo(&mybmp);
memset(&fbdev, 0, sizeof(FBDEV));
strcpy(fbdev.dev, FB_DEVICE );
if(fb_open(&fbdev)==FALSE)
{
printf("open frame buffer error\n");
return -1;
} DPRINTF("fbdev.fb_var.bits_per_pixel=%d\n",fbdev.fb_var.bits_per_pixel); DPRINTF("fbdev.fb_fix.smem_len=%d\n",fbdev.fb_fix.smem_len); DPRINTF("fbdev.fb_fix.line_length=%d\n",fbdev.fb_fix.line_length); ShowBitmapOnLCD(fbx,fby,&fbdev,&mybmp);
fb_close(&fbdev); UnLoadBitmap(&mybmp); DPRINTF("bitmap unloaded.\n"); return 0;
} /*清屏,color为颜色值0-255*/void ClearScreen(int color){ FBDEV fbdev;
memset(&fbdev, 0, sizeof(FBDEV));
strcpy(fbdev.dev, FB_DEVICE );
if(fb_open(&fbdev)==FALSE)
{
printf("open frame buffer error\n");
return;
} fb_memset((void *)(fbdev.fb_mem + fbdev.fb_mem_offset),color,fbdev.fb_fix.smem_len); fb_close(&fbdev);} /*得到fbx,fby处点的颜色*/short int DrawColor(int fbx,int fby){ short int dc; FBDEV fbdev;
memset(&fbdev, 0, sizeof(FBDEV));
strcpy(fbdev.dev, FB_DEVICE );
if(fb_open(&fbdev)==FALSE)
{
printf("open frame buffer error\n");
return -1;
} memcpy((char *)&dc,(void *)(fbdev.fb_mem+fbdev.fb_mem_offset+fbx*2 +fbdev.fb_fix.line_length*fby),2); fb_close(&fbdev); return dc;}/*在背景bgbmp上清除在(fbx,fby)处的图片file_name*/void ClearBitmap(int fbx,int fby,char *bgbmp,char *file_name){ BITMAP mybmp1,mybmp2; FBDEV fbdev; int i,x,y,w1,w2,h1,h2,line_len; unsigned int high,low; unsigned char r,g,b; FILE *bm_fp1,*bm_fp2; memset(&fbdev, 0, sizeof(FBDEV));
strcpy(fbdev.dev, FB_DEVICE ); if(fb_open(&fbdev)==FALSE)
{
printf("open frame buffer error\n");
return;
} LoadBitmap(&mybmp1,bgbmp); LoadBitmap(&mybmp2,file_name); bm_fp1=fopen(mybmp1.bmName,"r"); if(bm_fp1==NULL) { printf("can't open file %s!\n",mybmp1.bmName); return; } bm_fp2=fopen(mybmp2.bmName,"r"); if(bm_fp2==NULL) { printf("can't open file %s!\n",mybmp2.bmName); return; } w1=mybmp1.bmBMI.bmiHeader.biWidth; h1=mybmp1.bmBMI.bmiHeader.biHeight; w2=mybmp2.bmBMI.bmiHeader.biWidth; h2=mybmp2.bmBMI.bmiHeader.biHeight; /*由于行扫描时要DWORD对齐,所以要转换w*3的值 公式为:((width*biBitCount+31)>>5)<<2*/ w2=((w2*24+31)>>5)<<2; line_len=fbdev.fb_fix.line_length; for(y=0;y<h1;y++) { for(x=0;x<w1;x++) { i=h2*w2-(w2-3*(x+fbx))-(y+fby)*w2; fseek(bm_fp2,mybmp2.bmBF.bfOffBits+i,SEEK_SET); fread(&b,1,1,bm_fp2); fread(&g,1,1,bm_fp2); fread(&r,1,1,bm_fp2); r=(r&0xF8); g=(g&0xFC); b=(b&0xF8); high=r|(g>>5); low=(g<<3)|(b>>3); fb_memset((void *)(fbdev.fb_mem+fbdev.fb_mem_offset +line_len*(fby+y)+(fbx+x)*2),low,1); fb_memset((void *)(fbdev.fb_mem+fbdev.fb_mem_offset +line_len*(fby+y)+(fbx+x)*2+1),high,1); } } fb_close(&fbdev); UnLoadBitmap(&mybmp1); UnLoadBitmap(&mybmp2);}/*以触摸屏返回的坐标值(touch_x,touch_y)经转换使位图显示在LCD上*/int ShowBitmapWithTS(int touch_x,int touch_y,char *filename){ int ret; double xmin,xmax,ymin,ymax,xpp,ypp; /*x[4],y[4]需根据不通触摸屏进行修改*/ int x[4]={230,260,3550,3500},y[4]={450,460,3800,3700}; xmin=(x[0]+x[1])/2; xmax=(x[2]+x[3])/2; ymin=(y[0]+y[1])/2; ymax=(y[2]+y[3])/2; xpp=(xmax-xmin)/640; ypp=(ymax-ymin)/480; DPRINTF("touch:x=%d,y=%d\n",touch_x,touch_y); touch_x=(int)((touch_x-xmin)/xpp-25); touch_y=(int)((ymax-touch_y)/ypp-25); DPRINTF("calibration:x=%d,y=%d\n",touch_x,touch_y); ret=ShowBitmap(touch_x,touch_y,filename); return ret; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -