⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loadbmp.c

📁 在ARM2410开发板的LCD上显示未加密bmp图片的源码
💻 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 + -