ubuntu12.10 32位系统使用framebuffer显示24深度bmp文件

参考了网上很多例子,但是大多数都是有问题,只能显示部分,而且图片不是很清楚,在csdn上下载了一个代码是ok的。

总结一下就是:

1.mmap的大小如何确定

2.bmp文件的保存顺序是由下到上层的。

3.fread( (char *)&pix, 1, sizeof(PIXEL), fp);每次读取bmp一个像素的结构体,那么这个结构体的成员变量都是char类似,对于24深度的BMP文件要保证整个结构体大小为3.

那么32位的实现就更加简单,只要修改一行代码即可。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <asm/types.h>
#include <string.h>
#include <errno.h>
#include <sys/user.h>
#include <linux/fb.h>
#include <malloc.h>

#include "fbv.h"
#define BMP_TORASTER_OFFSET 10
#define BMP_SIZE_OFFSET 18
#define BMP_BPP_OFFSET 28
#define BMP_RLE_OFFSET 30
#define BMP_COLOR_OFFSET 54
int openFB(const char *name);
void closeFB(int fh);
void getVarScreenInfo(int fh, struct fb_var_screeninfo *var);
void getFixScreenInfo(int fh, struct fb_fix_screeninfo *fix);
#define fill4B(a) ( ( 4 - ( (a) % 4 ) ) & 0x03)

struct color {
unsigned char red;
unsigned char green;
unsigned char blue;
};

int show_pic(char*filename,int*x_offs,int*y_offs,int *rot);

int openFB(const char *name)
{
int fh;
char *dev;

if(name == NULL){
dev = getenv("FRAMEBUFFER");
if(dev) name = dev;
else name = DEFAULT_FRAMEBUFFER;
}

if ((fh = open(name, O_RDWR)) == -1){
fprintf(stderr, "open %s: %s\n", name, strerror(errno));
exit(1);
}
return fh;
}

void closeFB(int fh)
{
close(fh);
}
void getVarScreenInfo(int fh, struct fb_var_screeninfo *var)
{
if (ioctl(fh, FBIOGET_VSCREENINFO, var)){
fprintf(stderr, "ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno));
exit(1);
}
}

void getFixScreenInfo(int fh, struct fb_fix_screeninfo *fix)
{
if (ioctl(fh, FBIOGET_FSCREENINFO, fix)){
fprintf(stderr, "ioctl FBIOGET_FSCREENINFO: %s\n", strerror(errno));
exit(1);
}
}

int show_pic(char*filename,int*x_offs,int*y_offs,int *rot )
//int bmp_display(unsigned char *rgbbuff,int x_size, int y_size,int*x_offs,int*y_offs,int bpp)
{
uint32_t offset;
uint8_t color[4];
int width = 0, height = 0;
char tmp_buff[1*1*3] = "";
char* tmp = &tmp_buff;//(unsigned char *)(rgbbuff);
unsigned long fb_mem_offset;
unsigned long fb_mem;
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
int fd, raster, k, skip;
unsigned char buff[4];
//unsigned char *wr_buffer = buffer + x*(y-1)*3;
struct color pallete[256];
char filename1[] = "./1-24.bmp";

int x_size = 800;
int y_size = 600;
int bpp = 0;
int fh=-1;
fh = openFB(NULL);

int i=0,j=0;
int bit4_flag = 0;
int bit2_flag = 0;
printf("x_size=%d y_size=%d\n", x_size, y_size);
printf("x_offs=%d y_offs=%d\n", *x_offs, *y_offs);
getVarScreenInfo(fh, &var);
getFixScreenInfo(fh, &fix);

fb_mem_offset = (unsigned long)(fix.smem_start) & (~PAGE_MASK);
fb_mem = (unsigned long int)mmap(NULL, fix.smem_len + fb_mem_offset,
PROT_READ | PROT_WRITE, MAP_SHARED, fh, 0);
if (-1L == (long)fb_mem)
{
printf("mmap error! mem:%ld offset:%ld\n", fb_mem, fb_mem_offset);
return -1;
}
printf("mmap fix.smem_len:%d fb_mem_offset:%d (~PAGE_MASK)=%d\n", fix.smem_len, fb_mem_offset, (~PAGE_MASK));
printf("fix.smem_len + fb_mem_offset=%d y_size=%d\n", (fix.smem_len + fb_mem_offset), y_size);
width = *x_offs + x_size;
height = *y_offs + y_size;
fd = open(filename1, O_RDONLY);
if (fd == -1) {
return(FH_ERROR_FILE);
}

if (lseek(fd, BMP_TORASTER_OFFSET, SEEK_SET) == -1) {
return(FH_ERROR_FORMAT);
}
read(fd, buff, 4);
raster = buff[0] + (buff[1]<<8) + (buff[2]<<16) + (buff[3]<<24);

if (lseek(fd, BMP_BPP_OFFSET, SEEK_SET) == -1) {
return(FH_ERROR_FORMAT);
}
read(fd, buff, 2);
bpp = buff[0] + (buff[1]<<8);


lseek(fd, raster, SEEK_SET);
for(i = *y_offs; i < height; i++)
{
for(j = *x_offs; j < width; j++)
{
// DBG_INFO("i=%d--j=%d\n",i, j);
switch (bpp)
{
case 24:
memset(tmp_buff, 0, 3);
read(fd, tmp, 3);
color[0] = tmp[2];
color[1] = tmp[1];
color[2] = tmp[0];
color[3] = 0x00;
offset = (j + var.xoffset) * (var.bits_per_pixel/8) + (y_size - i + var.yoffset) * fix.line_length;
memcpy((void*)(fb_mem + offset), color, 4);
// tmp = tmp + 3;

break;
default:
printf("BMP BitCount isn't 1/4/8/24, so is err!\n");
}
}

}
closeFB(fh);
return 0;
}
int main(int argc,char *argv[])
{
char *filename;
int rot,x_offs,y_offs;

if(argc < 2)
{
// help(argv[0]);
fprintf(stderr, "Error: Required argument missing.\n");
return(1);
}

filename = argv[1];
if(argv[2]==NULL)
x_offs = 0;
else {x_offs =atoi(argv[2]);}

if(argv[3]==NULL)
y_offs = 20;
else y_offs =atoi(argv[3]);

if(argv[4]==NULL)
{
rot = 0;
}
else rot =atoi(argv[4]);

if(show_pic(filename,&x_offs,&y_offs,&rot))
//if(show_pic(filename,&x_offs,&y_offs,&rot))
{
printf("Error!Cannot display the picture!\nI'm main()!\n");
return -1;
}
printf("--------------------------------------------------------------------------------------------------------------------------------\n");
return 0;
}

//fbv.h文件内容

#define FH_ERROR_OK 0
#define FH_ERROR_FILE 1        /* read/access error */
#define FH_ERROR_FORMAT 2    /* file format error */
#define DEFAULT_FRAMEBUFFER "/dev/fb0"

int bmp_display(unsigned char *rgbbuff,int x_size, int y_size,int*x_offs,int*y_offs,int bpp);

int fh_bmp_load(char *name,unsigned char *buffer, unsigned char **alpha, int x,int y,int *bpp);
int fh_bmp_getsize(char *name,int *x,int *y);

/*
int fh_jpeg_load(char *name,unsigned char *buffer, unsigned char **alpha, int x,int y);
int fh_jpeg_getsize(char *name,int *x,int *y);

int fh_png_load(char *name,unsigned char *buffer, unsigned char **alpha, int x,int y);
int fh_png_getsize(char *name,int *x,int *y);

int fh_gif_load(char *name,unsigned char *buffer, unsigned char **alpha, int x,int y);
int fh_gif_getsize(char *name,int *x,int *y);
*/
struct image
{
    int width, height;
    unsigned char *rgb;
    unsigned char *alpha;
    int do_free;
};

#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值