使用linux的framebuffer接口在显示屏上显示图片

以下程序使用framebuffer接口在显示屏上显示一张图片,
注意图片尺寸被拉伸为屏幕的尺寸。
使用了opencv接口获取图片的像素数据。

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 

#include 
#include 

#include 
#include 
#include 
#include 

using namespace std;
using namespace cv;

#define RED  0xF800
#define GREEN  0x07E0
#define BLUE  0x001F

typedef cv::Point3_<uint8_t> Pixel;

typedef unsigned short color_t; /* 根据实际情况修改,此处为unsigned short是565的屏 */

static struct fb_var_screeninfo __g_vinfo; /* 显示信息 */
static color_t *__gp_frame; /* 虚拟屏幕首地址 */

int SCREEN_WIDTH;
int SCREEN_HEIGHT;

int framebuffer_init(void) {
	int fd = 0;
	fd = open("/dev/fb1", O_RDWR);
	if (fd == -1) {
		perror("fail to open /dev/fb1\n");
		return -1;
	}

	ioctl(fd, FBIOGET_VSCREENINFO, &__g_vinfo); /* 获取显示信息 */
	printf("bits_per_pixel = %d\n", __g_vinfo.bits_per_pixel); /* 一个像素点对应的位数,如果值为16则为565格式输出,如果值为32则为888格式输出 */
	printf("xres_virtual = %d\n", __g_vinfo.xres_virtual); /* 虚拟x轴像素点数 */
	printf("yres_virtual = %d\n", __g_vinfo.yres_virtual); /* 虚拟y轴像素点数 */
	printf("xres = %d\n", __g_vinfo.xres); /* x轴像素点数 */
	printf("yres = %d\n", __g_vinfo.yres); /* y轴像素点数 */

	SCREEN_WIDTH = __g_vinfo.xres;
	SCREEN_HEIGHT = __g_vinfo.yres;

	__gp_frame = (color_t*) mmap(NULL, /* 映射区的开始地址,为NULL表示由系统决定映射区的起始地址 */
			__g_vinfo.xres_virtual * __g_vinfo.yres_virtual
					* __g_vinfo.bits_per_pixel / 8, /* 映射区大小 */
			PROT_WRITE | PROT_READ, /* 内存保护标志(可读可写) */
			MAP_SHARED, /* 映射对象类型(与其他进程共享) */
			fd, /* 有效的文件描述符 */
			0); /* 被映射内容的偏移量 */
	if (__gp_frame == NULL) {
		perror("fail to mmap\n");
		return -1;
	}
	return 0;
}

inline uint16_t rgb888torgb565(uint8_t red, uint8_t green, uint8_t blue) {
	uint16_t b = (blue >> 3) & 0x1f;
	uint16_t g = ((green >> 2) & 0x3f) << 5;
	uint16_t r = ((red >> 3) & 0x1f) << 11;
	return (uint16_t) (r | g | b);
}

void full_screen(color_t color) {
	int i;
	color_t *p = __gp_frame;

	for (i = 0; i < __g_vinfo.xres_virtual * __g_vinfo.yres_virtual; i++) {
		*p++ = color;
	}
}

/**
 * https://www.cnblogs.com/siahekai/p/11000789.html
 * https://www.cnblogs.com/Jack-Lee/p/3652957.html
 */

void loop4() {
	while (1) {
		full_screen(RED);
		sleep(2);
		full_screen(GREEN);
		sleep(2);
		full_screen(BLUE);
		sleep(2);
		full_screen(RED | GREEN);
		sleep(2);
		full_screen(RED | GREEN | BLUE);
		sleep(2);
		full_screen(0);
		sleep(2);
	}
}

/**
 * first need to run insmod a2.ko
 *
 */
int main() {
	if (framebuffer_init()) {
		return -1;
	}
	full_screen(0);
	color_t *p1 = __gp_frame;
	Mat img = imread("in.jpg", IMREAD_UNCHANGED);

	printf("width %d\n", img.cols);
	printf("height %d\n", img.rows);

	Mat img2;
	resize(img, img2, Size(SCREEN_WIDTH, SCREEN_HEIGHT));
	for (Pixel p : Mat_<Pixel>(img2)) {
		*p1++ = rgb888torgb565(p.z, p.y, p.x);
	}
	return 0;
}


你可能感兴趣的:(图像处理,linux,运维,服务器)