标题popen()函数
功能:获取执行的程序输出的内容到缓存区
案例:
利用popen加载开发板中的所有图片,并循环显示一次
在这里插入代码片#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
//__attribute__((packed)) 把一个结构体压实,自己根据数据的大小分配空间,不进行对齐!
// 14个字节文件头
struct BITMAPFILEHEADER
{
unsigned short bfType; // 文件的类型,该值必需是0x4D42,也就是字符'BM'。
unsigned int bfSize; // 位图文件的大小,用字节为单位
unsigned short bfReserved1; // 保留,必须设置为0
unsigned short bfReserved2; // 保留,必须设置为0
unsigned int bfOffBits; // 位图数据距离文件开头偏移量,用字节为单位
} __attribute__((packed));
// 40个字节的信息头
struct WINBMPINFOHEADER
{
unsigned int biSize; // BITMAPINFOHEADER结构所需要的字数
unsigned int biWidth; // 图像宽度,单位为像素
unsigned int biHeight; // 图像高度,单位为像素,负数,则说明图像是正向的
unsigned short biPlanes; // 为目标设备说明位面数,其值将总是被设为1
unsigned short biBitCount; // 一个像素占用的bit位,值位1、4、8、16、24、32
unsigned int biCompression; // 压缩类型
unsigned int biSizeImage; // 位图数据的大小,以字节为单位
unsigned int biXPelsPerMeter; // 水平分辨率,单位 像素/米
unsigned int biYPelsPerMeter; // 垂直分辨率,单位 像素/米
unsigned int biClrUsed; //
unsigned int biClrImportant; //
};
// 在px 和 py 的位置上显示pic图片
int show_24_bmp(char *pic, int px, int py)
{
// 1.打开LCD 设备
int lcd_fd = open("/dev/fb0", O_RDWR);
if (lcd_fd < 0)
{
perror("lcd_fd init fail:");
return -1;
}
// 2.进行内存映射
char *lcd_p = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, lcd_fd, 0);
if (lcd_p == MAP_FAILED)
{
perror("mmap fail:");
return -1;
}
// 解码图片
// 1.打开bmp图片
int fd = open(pic, O_RDWR);
if (fd < 0)
{
perror("打开图片失败\n");
return -1;
}
// 2.读取文件头
struct BITMAPFILEHEADER file_head;
read(fd, &file_head, sizeof(file_head));
// 3.读取信息头
struct WINBMPINFOHEADER msg_head;
read(fd, &msg_head, sizeof(msg_head));
// 输出 bmp 图像的信息
printf("格式%.2s\n", (char *)&file_head.bfType);
printf("大小%d\n", file_head.bfSize);
printf("Width=%d\n", msg_head.biWidth);
printf("Height=%d\n", msg_head.biHeight);
printf("位深=%d\n", msg_head.biBitCount);
// 根据图片的宽度和高度和位深,定义一个像素点缓存区
int w = msg_head.biWidth;
int h = msg_head.biHeight;
int bit = msg_head.biBitCount;
char rgb[w * h * bit / 8]; // bit/8 求出一个像素多少个字节
// 读取图片的像素数据到缓存区
read(fd, rgb, sizeof(rgb));
// 关闭图片
close(fd);
// 把24位图转换为32位图
// 把rgb转换为argb
char argb[w * h * 4]; // char argb[200*200*4];
for (int i = 0; i < w * h; i++)
{
argb[0 + i * 4] = rgb[0 + i * 3];
argb[1 + i * 4] = rgb[1 + i * 3];
argb[2 + i * 4] = rgb[2 + i * 3];
argb[3 + i * 4] = 0;
}
// 翻转放入LCD 设备中
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w * 4; x++) // 赋值一行
{
// 提示显示的时候,不要出界
lcd_p[(y + py) * 800 * 4 + (x + px * 4)] = argb[(h - 1 - y) * w * 4 + x];
}
}
// 解除映射
munmap(lcd_p, 800 * 480 * 4);
// 关闭LCD设备
close(lcd_fd);
}
// 利用popen加载开发板中的所有bmp图片,并循环显示一次
int main(int argc, char *argv[])
{
FILE *fp = popen("find / -name \"*.bmp\"", "r");
if (fp == NULL)
{
perror("加载失败");
return -1;
}
while (!feof(fp))
{
char buf[1024] = {0};
char *find = NULL;
fgets(buf, 1024, fp);
find = strchr(buf,'\n');
if (find)
*find = '\0';
show_24_bmp(buf, 0, 0);
sleep(1);
}
pclose(fp);
}
1.bmp的解码,一般bmp是24位的,而开发板是32位的,所以我们要把24位图片转换为32位图才能在开发板上显示。
2.用fgets函数会读取换行符,我们要去掉换行符,不然你打不开图片会显示如下错误:
解决办法是
char buf[1024] = {0};
char *find = NULL;
fgets(buf, 1024, fp);
find = strchr(buf,'\n');
if (find)
*find = '\0';
show_24_bmp(buf, 0, 0);
sleep(1);