导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页

    V853显示屏无法直接显示图片

    V Series
    4
    4
    2411
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • D
      ddrddr LV 5 最后由 编辑

      V853的芯片,接的是800*480的RGB屏幕。QT是可以正常显示的。从网上找了个通过fb的ioctrl去显示bmp图片的程序,执行后不论是什么图片都是显示黑屏。同样的应用程序在 V3S+同样的屏幕 是可以正常显示bmp图片的。也有用过fbv去显示图片,fbv xxxx.bmp 但也是显示全黑。
      有没有遇到同样问题的朋友帮忙解答一下呢?
      以下是显示bmp图片的应用程序:

      ···
      #include <unistd.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <fcntl.h>
      #include <string.h>
      #include <linux/fb.h>
      #include <sys/mman.h>
      #include <sys/ioctl.h>
      #include <arpa/inet.h>
      #include <errno.h>
      
      //14byte文件头
      typedef struct
      {
      	char cfType[2];  //文件类型,"BM"(0x4D42)
      	int  cfSize;     //文件大小(字节)
      	int  cfReserved; //保留,值为0
      	int  cfoffBits;  //数据区相对于文件头的偏移量(字节)
      }__attribute__((packed)) BITMAPFILEHEADER;
      //__attribute__((packed))的作用是告诉编译器取消结构在编译过程中的优化对齐
      
      //40byte信息头
      typedef struct
      {
      	char ciSize[4];          //BITMAPFILEHEADER所占的字节数
      	int  ciWidth;            //宽度
      	int  ciHeight;           //高度
      	char ciPlanes[2];        //目标设备的位平面数,值为1
      	int  ciBitCount;         //每个像素的位数
      	char ciCompress[4];      //压缩说明
      	char ciSizeImage[4];     //用字节表示的图像大小,该数据必须是4的倍数
      	char ciXPelsPerMeter[4]; //目标设备的水平像素数/米
      	char ciYPelsPerMeter[4]; //目标设备的垂直像素数/米
      	char ciClrUsed[4];       //位图使用调色板的颜色数
      	char ciClrImportant[4];  //指定重要的颜色数,当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要
      }__attribute__((packed)) BITMAPINFOHEADER;
      
      typedef struct
      {
      	unsigned char blue;
      	unsigned char green;
      	unsigned char red;
      	unsigned char reserved;
      }__attribute__((packed)) PIXEL; //颜色模式RGB
      
      
      
      typedef struct
      {
      	int          fbfd;
      	char         *fbp;
      	unsigned int xres;
      	unsigned int yres;
      	unsigned int xres_virtual;
      	unsigned int yres_virtual;
      	unsigned int xoffset;
      	unsigned int yoffset;
      	unsigned int bpp;
      	unsigned long line_length;
      	unsigned long size;
      
      	struct fb_bitfield red;
      	struct fb_bitfield green;
      	struct fb_bitfield blue;
      } FB_INFO;
      
      typedef struct
      {
      	unsigned int width;
      	unsigned int height;
      	unsigned int bpp;
      	unsigned long size;
      	unsigned int data_offset;
      } IMG_INFO;
      
      
      
      FB_INFO fb_info;
      IMG_INFO img_info;
      
      int show_bmp(char *img_name);
      
      static int cursor_bitmap_format_convert(char *dst,char *src, unsigned long img_len_one_line)
      {
      	int img_len ,fb_len ;
      	char *p;
      	__u32 val;
      	PIXEL pix;
      
      	p = (char *)&val;
      
      	img_len = img_info.width; /*一行图片的长度*/
      	fb_len = fb_info.xres; /*一行显示屏的长度*/
      
      	/*进行x轴的偏移*/
      	dst += fb_info.xoffset * (fb_info.bpp / 8);
      	fb_len -= fb_info.xoffset;
      
      	/*bmp 数据是上下左右颠倒的,这里只进行左右的处理*/
      	/*先定位到图片的最后一个像素的地址,然后往第一个像素的方向处理,进行左右颠倒的处理*/
      	src += img_len_one_line - 1;
      
      	/*处理一行要显示的数据*/
      	while(1) {
      		if (img_info.bpp == 32)
      			pix.reserved = *(src--);
      		pix.red   = *(src--);
      		pix.green = *(src--);
      		pix.blue  = *(src--);
      
      		val = 0x00;
      		val |= (pix.red >> (8 - fb_info.red.length)) << fb_info.red.offset;
      		val |= (pix.green >> (8 - fb_info.green.length)) << fb_info.green.offset;
      		val |= (pix.blue >> (8 - fb_info.blue.length)) << fb_info.blue.offset;
      		val = 0x000000;
      
      
      		if (fb_info.bpp == 16) {
      			*(dst++) = *(p + 0);
      			*(dst++) = *(p + 1);
      		}
      		else if (fb_info.bpp == 24) {
      			*(dst++) = *(p + 0);
      			*(dst++) = *(p + 1);
      			*(dst++) = *(p + 2);
      		}
      		else if (fb_info.bpp == 32) {
      			*(dst++) = *(p + 0);
      			*(dst++) = *(p + 1);
      			*(dst++) = *(p + 2);
      			*(dst++) = *(p + 3);
      		}
      
      		/*超过图片长度或显示屏长度认为一行处理完了*/
      		img_len--;
      		fb_len--;
      		if (img_len <= 0 || fb_len <= 0)
      			break;
      	}
      #if 0
      	printf("r = %d\n", pix.red);
      	printf("g = %d\n", pix.green);
      	printf("b = %d\n", pix.blue);
      #endif
      	return 0;
      }
      
      int show_bmp(char *img_name)
      {
      
      	FILE *fp;
      	int ret = 0;
      	BITMAPFILEHEADER FileHead;
      	BITMAPINFOHEADER InfoHead;
      
      	if(img_name == NULL) {
      		printf("img_name is null\n");
      		return -1;
      	}
      
      	fp = fopen( img_name, "rb" );
      	if(fp == NULL) {
      		printf("img[%s] open failed\n", img_name);
      		ret = -1;
      		goto err_showbmp;
      	}
      
      	/* 移位到文件头部 */
      	fseek(fp, 0, SEEK_SET);
      
      	ret = fread(&FileHead, sizeof(BITMAPFILEHEADER), 1, fp);
      	if ( ret != 1) {
      		printf("img read failed\n");
      		ret = -1;
      		goto err_showbmp;
      	}
      
      	//检测是否是bmp图像
      	if (memcmp(FileHead.cfType, "BM", 2) != 0) {
      		printf("it's not a BMP file[%c%c]\n", FileHead.cfType[0], FileHead.cfType[1]);
      		ret = -1;
      		goto err_showbmp;
      	}
      
      	ret = fread( (char *)&InfoHead, sizeof(BITMAPINFOHEADER),1, fp );
      	if ( ret != 1) {
      		printf("read infoheader error!\n");
      		ret = -1;
      		goto err_showbmp;
      	}
      
      	img_info.width       = InfoHead.ciWidth;
      	img_info.height      = InfoHead.ciHeight;
      	img_info.bpp         = InfoHead.ciBitCount;
      	img_info.size        = FileHead.cfSize;
      	img_info.data_offset = FileHead.cfoffBits;
      
      	printf("img info w[%d] h[%d] bpp[%d] size[%ld] offset[%d]\n", img_info.width, img_info.height, img_info.bpp, img_info.size, img_info.data_offset);
      
      	if (img_info.bpp != 24 && img_info.bpp != 32) {
      		printf("img bpp is not 24 or 32\n");
      		ret = -1;
      		goto err_showbmp;
      	}
      
      
      	/*
      	 *一行行处理
      	 */
      	char *buf_img_one_line;
      	char *buf_fb_one_line;
      	char *p;
      	int fb_height;
      
      	long img_len_one_line = img_info.width * (img_info.bpp / 8);
      	long fb_len_one_line = fb_info.line_length;
      
      //	printf("img_len_one_line = %d\n", img_len_one_line);
      //	printf("fb_len_one_line = %d\n", fb_info.line_length);
      
      	buf_img_one_line = (char *)calloc(1, img_len_one_line + 256);
      	if(buf_img_one_line == NULL) {
      		printf("alloc failed\n");
      		ret = -1;
      		goto err_showbmp;
      	}
      
      	buf_fb_one_line = (char *)calloc(1, fb_len_one_line + 256);
      	if(buf_fb_one_line == NULL) {
      		printf("alloc failed\n");
      		ret = -1;
      		goto err_showbmp;
      	}
      
      
      	fseek(fp, img_info.data_offset, SEEK_SET);
      
      	p = fb_info.fbp + fb_info.yoffset * fb_info.line_length; /*进行y轴的偏移*/
      	fb_height = fb_info.yres;
      	while (1) {
      		memset(buf_img_one_line, 0, img_len_one_line);
      		memset(buf_fb_one_line, 0, fb_len_one_line);
      		ret = fread(buf_img_one_line, 1, img_len_one_line, fp);
      		if (ret < img_len_one_line) {
      			/*图片读取完成,则图片显示完成*/
      			printf("read to end of img file\n");
      			cursor_bitmap_format_convert(buf_fb_one_line, buf_img_one_line, img_len_one_line); /*数据转换*/
      			memcpy(fb_info.fbp, buf_fb_one_line, fb_len_one_line);
      			break;
      		}
      
      		cursor_bitmap_format_convert(buf_fb_one_line, buf_img_one_line, img_len_one_line); /*数据转换*/
      		memcpy(p, buf_fb_one_line, fb_len_one_line); /*显示一行*/
      		p += fb_len_one_line;
      
      		/*超过显示屏宽度认为图片显示完成*/
      		fb_height--;
      		if (fb_height <= 0)
      			break;
      	}
      
      	free(buf_img_one_line);
      	free(buf_fb_one_line);
      
      	fclose(fp);
      	return ret;
      err_showbmp:
      	if (fp)
      		fclose(fp);
      	return ret;
      }
      
      int show_picture(char *img_name)
      {
      	struct fb_var_screeninfo vinfo;
      	struct fb_fix_screeninfo finfo;
      
      	if (fb_info.fbfd <= -1) {
      		printf("fb open fialed\n");
      		return -1;
      	}
      
      	if (ioctl(fb_info.fbfd, FBIOGET_FSCREENINFO, &finfo)) {
      		printf("fb ioctl fialed\n");
      		return -1;
      	}
      
      	if (ioctl(fb_info.fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
      		printf("fb ioctl fialed\n");
      		return -1;
      	}
      
      	fb_info.xres = vinfo.xres;
      	fb_info.yres = vinfo.yres;
      	fb_info.xres_virtual = vinfo.xres_virtual;
      	fb_info.yres_virtual = vinfo.yres_virtual;
      	fb_info.xoffset = vinfo.xoffset;
      	fb_info.yoffset = vinfo.yoffset;
      	fb_info.bpp  = vinfo.bits_per_pixel;
      	fb_info.line_length = finfo.line_length;
      	fb_info.size = finfo.smem_len;
      
      	memcpy(&fb_info.red, &vinfo.red, sizeof(struct fb_bitfield));
      	memcpy(&fb_info.green, &vinfo.green, sizeof(struct fb_bitfield));
      	memcpy(&fb_info.blue, &vinfo.blue, sizeof(struct fb_bitfield));
      
      #if 1
      	printf("fb info x[%d] y[%d] x_v[%d] y_v[%d] xoffset[%d] yoffset[%d] bpp[%d] line_length[%ld] size[%ld]\n", fb_info.xres, fb_info.yres, fb_info.xres_virtual, fb_info.yres_virtual, fb_info.xoffset, fb_info.yoffset, fb_info.bpp, fb_info.line_length, fb_info.size);
      
      	printf("fb info red off[%d] len[%d] msb[%d]\n", fb_info.red.offset, fb_info.red.length, fb_info.red.msb_right);
      	printf("fb info green off[%d] len[%d] msb[%d]\n", fb_info.green.offset, fb_info.green.length, fb_info.green.msb_right);
      	printf("fb info blue off[%d] len[%d] msb[%d]\n", fb_info.blue.offset, fb_info.blue.length, fb_info.blue.msb_right);
      #endif
      
      	if (fb_info.bpp != 16 && fb_info.bpp != 24 && fb_info.bpp != 32) {
      		printf("fb bpp is not 16,24 or 32\n");
      		return -1;
      	}
      
      	if (fb_info.red.length > 8 || fb_info.green.length > 8 || fb_info.blue.length > 8) {
      		printf("fb red|green|blue length is invalid\n");
      		return -1;
      	}
      
      	// 内存映射
      	fb_info.fbp = (char *)mmap(0, fb_info.size, PROT_READ | PROT_WRITE, MAP_SHARED, fb_info.fbfd, 0);
      	if (fb_info.fbp == (char *)-1) {
      		printf("mmap fialed\n");
      		return -1;
      	}
      
      	show_bmp(img_name);
      
      	//删除映射
      	munmap(fb_info.fbp, fb_info.size);
      
      	return 0;
      }
      
      
      int main(int argc, char **argv)
      {
      	char img_name[64];
      
      	if (argc != 2) {
      		printf("arg error\n");
      		return 0;
      	}
      
      	snprintf(img_name, sizeof(img_name), "%s", argv[1]);
      	printf("img_name = %s\n", img_name);
      
      	fb_info.fbfd = open("/dev/fb0", O_RDWR);
      	if (!fb_info.fbfd) {
      		printf("Error: cannot open framebuffer device(/dev/fb0).\n");
      		return -1;
      	}
      	show_picture(img_name);
      
      	close(fb_info.fbfd);
      		return 0;
      }
      ···
      

      只能是通过QT显示图片后,将/dev/fb0里面的数据抓出来,要显示的时候再cat这个数据到fb0里显示。有哪位大神知道是什么原因导致的吗?

      A Gadyellow L 3 条回复 最后回复 回复 引用 分享 1
      • A
        awwwwa LV 8 @ddrddr 最后由 编辑

        @ddrddr 看一下图层的设置,是否有图层覆盖

        1 条回复 最后回复 回复 引用 分享 0
        • Gadyellow
          Gadyellow LV 5 @ddrddr 最后由 编辑

          @ddrddr 请问您解决了吗,我也遇到了相同的问题

          1 条回复 最后回复 回复 引用 分享 0
          • L
            laocai LV 5 @ddrddr 最后由 编辑

            @ddrddr 可能你的framebuffer支持alpha通道,但是填充图像数据的时候没有填写相应alpha数值。检查一下framebuffer格式即可。

            1 条回复 最后回复 回复 引用 分享 0
            • 1 / 1
            • First post
              Last post

            Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

            行为准则 | 用户协议 | 隐私权政策