目录
1 . 实现图图片的打印
1)结构体定义
2)画点线
3)清屏
4)图片显示
5)主函数部分
2 . 实现字符的打印
1) 定义BMP位图文件的头部信息以及信息头
2)实现打印字符的绘制
3 . 打印文本内容
附录
1 . 实现图图片的打印
1)结构体定义
2)画点线
3)清屏
4)图片显示
从给定的BMP文件路径(pathname
)中读取图像数据,并在一个图形界面上(通过draw_point
函数)以某种方式显示这些图像数据
部分解释:
分配内存并读取图像数据
这里表示代码假定的图像尺寸(400x320像素,每个像素3个字节)计算了图像数据的大小,并分配了足够的内存来存储这些数据。然后,它从文件中读取了这些数据。
遍历并绘制图像
这部分代码遍历了图像数据的每个像素。它首先定义了一个
col
结构体,用于存储当前像素的颜色值。然后,它逐个字节地从data
指针指向的数组中读取蓝色、绿色、红色的值,并将它们存储在c
结构体中。
(y0 + 320 - j - 1)
来计算y坐标,这通常是因为图像在BMP文件中是以“倒序”存储的(第一行是图像的底部从左下角开始,最后一行是图像的顶部)为了正确地在屏幕上显示图像,需要对y坐标进行这样的调整从左下角开始一行一行往上走
5)主函数部分
show_bmp("./2.bmp", 100, 200); // 确定图片以及坐标
2 . 实现字符的打印
1) 定义BMP位图文件的头部信息以及信息头
- 预处理指令
#pragma pack(2)
和#pragma pack(4)
:
#pragma pack(n)
是一个编译器指令,用于控制结构体成员的对齐方式。n
指定了每个成员在内存中的对齐字节数。在这个例子中,首先使用#pragma pack(2)
来设置结构体成员的对齐为2字节(这通常是为了确保结构体在文件中占用的空间与文件格式规范相匹配),然后在定义完_tag_bmp_file_head
结构体后,使用#pragma pack(4)
恢复到默认的对齐方式(或指定为4字节对齐,这取决于编译器的默认行为)。
2)实现打印字符的绘制
3 . 打印文本内容
部分代码解释
void draw_string(char *str, int x0, int y0, col f) { int len = strlen(str); // 获取字符串的长度 int i; // 声明循环变量 for (i = 0; i < len; i++) // 遍历字符串中的每个字符 { switch (*str) // 这里的问题在于它总是检查字符串的第一个字符(*str) { case '\r': // 遇到回车符,将x0重置为0 x0 = 0; break; case '\n': // 遇到换行符,将x0重置为0并增加y0 x0 = 0; y0 += 16; // 假设每个字符/行高为16像素 break; case '\t': // 遇到制表符,这里没有实现任何功能 break; case '\b': // 遇到退格符,这里也没有实现任何功能 break; default: // 默认情况下,绘制当前字符并更新x0 draw_a_ascii(x0, y0, *str, f); // 调用假设存在的绘图函数 x0 += 8; // 假设每个字符宽度为8像素 str++; break; } } }
unsigned char *pzimo = (void *)(font_8x16 + (int)ch * 16UL);
(int)ch * 16UL
计算出ch
字符在font_8x16
数组中的偏移量(假设每个字符占用16字节)。然后,它使用这个偏移量从font_8x16
数组的起始地址加上这个偏移量,得到指向该字符8x16位图数据的指针pzimo
运行 linux
crtl + alt + F5
ctrl + alt + Fn + F1 退出
显示
附录
1 #include <stdio.h> 2 #include <sys/stat.h> 3 #include <sys/types.h> 4 #include <fcntl.h> 5 #include <sys/ioctl.h> 6 #include <linux/fb.h> 7 #include <sys/mman.h> 8 #include <unistd.h> 9 #include <stdlib.h> 10 #include <math.h> 11 12 struct fb_var_screeninfo info; 13 unsigned char * p_fd = NULL; 14 15 typedef struct __color 16 { 17 unsigned char b; 18 unsigned char g; 19 unsigned char r; 20 unsigned char null; 21 }color; 22 23 typedef union 24 { 25 color rgb; 26 unsigned int l; 27 }col; 28 29 int draw_point(int x0, int y0, col c) 30 { 31 if((x0 < 0) || (x0 > info.xres_virtual)) 32 return -1; 33 if((y0 < 0) || (y0 > info.yres_virtual)) 34 return -1; 35 36 unsigned int * p = (unsigned int *)(p_fd + (y0 * info.xres_virtual + x0) * 4); 37 *p = c.l; 38 39 return 0; 40 } 41 int draw_h_line(int x0, int y0, int len, col c) 42 { 43 int i = 0; 44 for(i = 0; i < len; i++) 45 { 46 draw_point(x0 + i, y0, c); 47 } 48 49 return 0; 50 } 51 52 int clr_bg() 53 { 54 int i = 0; 55 col c; 56 c.l = 0; 57 for(i = 0; i < 600; i++) 58 { 59 draw_h_line(0, i, info.yres, c); 60 } 61 } 62 int show_bmp(const char * pathname, int x0, int y0) 63 { 64 int fd = open(pathname, O_RDWR); 65 if(fd < 0) 66 { 67 perror("open bmp failed\n"); 68 return -1; 69 } 70 71 unsigned char buf[54] = {0}; 72 read(fd, buf, sizeof(buf)); 73 74 int size = 400 * 320 * 3; 75 unsigned char * data = malloc(size); 76 read(fd, data, size); 77 unsigned char * p = data; 78 79 int i = 0; 80 int j = 0; 81 for(j = 0; j < 320; j++) // y 82 { 83 for(i = 0; i < 400; i++) // x 84 { 85 col c; 86 c.rgb.b = *p++; 87 c.rgb.g = *p++; 88 c.rgb.r = *p++; 89 #if 0 90 c.rgb.b = data[(j * 400 + i) * 3]; 91 c.rgb.g = data[(j * 400 + i) * 3 + 1]; 92 c.rgb.r = data[(j * 400 + i) * 3 + 2]; 93 #endif 94 draw_point(x0 + i, y0 + 320 - j - 1, c); 95 } 96 } 97 98 free(data); 99 close(fd); 100 } 101 102 int main(int argc, const char *argv[]) 103 { 104 //open 105 int fd = open("/dev/fb0", O_RDWR); 106 if(fd < 0) 107 { 108 perror("open fd failed:"); 109 return fd; 110 } 111 112 //get_screen_info 113 int ret = ioctl(fd, FBIOGET_VSCREENINFO, &info); 114 if(ret < 0) 115 { 116 perror("ioctl failed:"); 117 return ret; 118 } 119 printf("xres = %d yres = %d\n", 120 info.xres, info.yres); 121 printf("xres_virtual = %d yres_virtual = %d\n", 122 info.xres_virtual, info.yres_virtual); 123 printf("bits_per_pixel = %d\n", info.bits_per_pixel); 124 125 //mmap 126 unsigned long size = info.xres_virtual * info.yres_virtual * info.bits_per_pixel / 8; 127 p_fd = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0); 128 if(NULL == p_fd) 129 { 130 perror("mmap failed:"); 131 return -3; 132 } 133 show_bmp("./2.bmp", 100, 200); 134 //munmap 135 munmap(p_fd, size); 136 //close 137 close(fd); 138 return 0; 139 } 140 ~
1 #include <stdio.h> 2 #include <sys/stat.h> 3 #include <sys/types.h> 4 #include <fcntl.h> 5 #include <sys/ioctl.h> 6 #include <linux/fb.h> 7 #include <sys/mman.h> 8 #include <unistd.h> 9 #include <stdlib.h> 10 #include <math.h> 11 #include <string.h> 12 13 struct fb_var_screeninfo info; 14 unsigned char * p_fd = NULL; 15 16 typedef struct __color 17 { 18 unsigned char b; 19 unsigned char g; 20 unsigned char r; 21 unsigned char null; 22 }color; 23 24 typedef union 25 { 26 color rgb; 27 unsigned int l; 28 }col; 29 30 int draw_point(int x0, int y0, col c) 31 { 32 if((x0 < 0) || (x0 > info.xres_virtual)) 33 return -1; 34 if((y0 < 0) || (y0 > info.yres_virtual)) 35 return -1; 36 37 unsigned int * p = (unsigned int *)(p_fd + (y0 * info.xres_virtual + x0) * 4); 38 *p = c.l; 39 40 return 0; 41 } 42 43 int draw_h_line(int x0, int y0, int len, col c) 44 { 45 int i = 0; 46 for(i = 0; i < len; i++) 47 { 48 draw_point(x0 + i, y0, c); 49 } 50 51 return 0; 52 } 53 54 int clr_bg() 55 { 56 int i = 0; 57 col c; 58 c.l = 0xffffff; 59 for(i = 0; i < 600; i++) 60 { 61 draw_h_line(0, i, info.xres, c); 62 } 63 } 64 65 #define PI 3.1415926 66 #pragma pack(2) 67 typedef struct _tag_bmp_file_head{ 68 unsigned short file_type; // 位图文件的类型,必须为BMP (2个字节) 69 unsigned int file_size; // 位图文件的大小,以字节为单位 (4个字节) 70 unsigned short file_reserved1; // 位图文件保留字,必须为0 (2个字节) 71 unsigned short file_reserved2; // 位图文件保留字,必须为0 (2个字节) 72 unsigned int file_offset_bits; // 位图数据的起始位置,以相对于位图 (4个字节) 73 }bmp_file_head; 74 75 typedef struct _tag_bmp_info_head{ 76 unsigned int info_size; // 本结构所占用字节数 (4个字节) 77 unsigned int bit_width; // 位图的宽度,以像素为单位(4个字节) 78 unsigned int bit_height; // 位图的高度,以像素为单位(4个字节) 79 unsigned short bit_planes; // 目标设备的级别,必须为1(2个字节) 80 unsigned short bits_per_pixel; // 每个像素所需的位数,必须是1(双色)、// 4(16色)、8(256色)、 81 // 24(真彩色)或32(增强真彩色)之一 (2个字节) 82 unsigned int bit_compression; // 位图压缩类型,必须是 0(不压缩)、 1(BI_RLE8 83 // 压缩类型)或2(BI_RLE4压缩类型)之一 ) (4个字节) 84 unsigned int bit_sizeImage; // 位图的大小,以字节为单位(4个字节) 85 unsigned int bit_xpels_per_meter; // 位图水平分辨率,每米像素数(4个字节) 86 unsigned int bit_ypels_per_meter; // 位图垂直分辨率,每米像素数(4个字节) 87 unsigned int bit_clr_used; // 位图实际使用的颜色表中的颜色数(4个字节) 88 unsigned int bit_clr_important; // 位图显示过程中重要的颜色数(4个字节) 89 }bmp_info_head; 90 91 #pragma pack(4) 92 int draw_a_ascii(char ch, int x0, int y0, col c) 93 { 94 unsigned char data[8] = {0x0,0x38,0x24,0x24,0x38,0x24,0x24,0x38}; //B 95 int i = 2; 96 int j = 0; 97 printf("x0 = %d y0 = %d\n", x0, y0) ; 98 for(j = 0; j < 8; j++) 99 { 100 unsigned char tmp = data[j]; 101 for(i = 0; i < 8; i++) 102 { 103 if(0x80 & (tmp << i)) 104 { 105 draw_point(x0 + i, y0 + j, c); 106 } 107 } 108 } 109 return 0; 110 } 111 112 int draw_str(const char * str, int x0, int y0, col c) 113 { 114 int len = strlen(str); 115 int i = 0; 116 int x = x0; 117 int y = y0; 118 for(i = 0; i < len; i++) 119 { 120 switch(str[i]) 121 { 122 case '\n': 123 y += 9; 124 x = x0; 125 break; 126 case ' ': 127 x += 9; 128 default: 129 draw_a_ascii(str[i], x, y, c); 130 x += 9; 131 break; 132 } 133 } 134 return 0; 135 } 136 137 int main(int argc, const char *argv[]) 138 { 139 //open 140 int fd = open("/dev/fb0", O_RDWR); 141 if(fd < 0) 142 { 143 perror("open fd failed:"); 144 return fd; 145 } 146 147 //get_screen_info 148 int ret = ioctl(fd, FBIOGET_VSCREENINFO, &info); 149 if(ret < 0) 150 { 151 perror("ioctl failed:"); 152 return ret; 153 } 154 printf("xres = %d yres = %d\n", 155 info.xres, info.yres); 156 printf("xres_virtual = %d yres_virtual = %d\n", 157 info.xres_virtual, info.yres_virtual); 158 printf("bits_per_pixel = %d\n", info.bits_per_pixel); 159 160 //mmap 161 unsigned long size = info.xres_virtual * info.yres_virtual * info.bits_per_pixel / 8; 162 p_fd = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0); 163 if(NULL == p_fd) 164 { 165 perror("mmap failed:"); 166 return -3; 167 } 168 169 col c; 170 c.rgb.r = 0xff; 171 c.rgb.g = 0xff; 172 c.rgb.b = 0xff; 173 174 clr_bg(); 175 176 col c1; 177 c1.l = 0; 178 c1.rgb.r = 0xff; 179 180 draw_str("12345\n123 456\n1234567", 100, 100, c1); 181 182 //munmap 183 munmap(p_fd, size); 184 //close 185 close(fd); 186 return 0; 187 } 188
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
struct fb_var_screeninfo info;
unsigned char * p_fd = NULL;
typedef struct __color
{
unsigned char b;
unsigned char g;
unsigned char r;
unsigned char null;
}color;
typedef union
{
color rgb;
unsigned int l;
}col;
int draw_point(int x0, int y0, col c)
{
if((x0 < 0) || (x0 > info.xres_virtual))
return -1;
if((y0 < 0) || (y0 > info.yres_virtual))
return -1;
unsigned int * p = (unsigned int *)(p_fd + (y0 * info.xres_virtual + x0) * 4);
*p = c.l;
return 0;
}
int draw_h_line(int x0, int y0, int len, col c)
{
int i = 0;
for(i = 0; i < len; i++)
{
draw_point(x0 + i, y0, c);
}
return 0;
}
int clr_bg()
{
int i = 0;
col c;
c.l = 0xffffff;
for(i = 0; i < 600; i++)
{
draw_h_line(0, i, info.xres, c);
}
}
#pragma pack(2)
typedef struct _tag_bmp_file_head{
unsigned short file_type; // 位图文件的类型,必须为BMP (2个字节)
unsigned int file_size; // 位图文件的大小,以字节为单位 (4个字节)
unsigned short file_reserved1; // 位图文件保留字,必须为0 (2个字节)
unsigned short file_reserved2; // 位图文件保留字,必须为0 (2个字节)
unsigned int file_offset_bits; // 位图数据的起始位置,以相对于位图 (4个字节)
}bmp_file_head;
typedef struct _tag_bmp_info_head{
unsigned int info_size; // 本结构所占用字节数 (4个字节)
unsigned int bit_width; // 位图的宽度,以像素为单位(4个字节)
unsigned int bit_height; // 位图的高度,以像素为单位(4个字节)
unsigned short bit_planes; // 目标设备的级别,必须为1(2个字节)
unsigned short bits_per_pixel; // 每个像素所需的位数,必须是1(双色)、// 4(16色)、8(256色)、
// 24(真彩色)或32(增强真彩色)之一 (2个字节)
unsigned int bit_compression; // 位图压缩类型,必须是 0(不压缩)、 1(BI_RLE8
// 压缩类型)或2(BI_RLE4压缩类型)之一 ) (4个字节)
unsigned int bit_sizeImage; // 位图的大小,以字节为单位(4个字节)
unsigned int bit_xpels_per_meter; // 位图水平分辨率,每米像素数(4个字节)
unsigned int bit_ypels_per_meter; // 位图垂直分辨率,每米像素数(4个字节)
unsigned int bit_clr_used; // 位图实际使用的颜色表中的颜色数(4个字节)
unsigned int bit_clr_important; // 位图显示过程中重要的颜色数(4个字节)
}bmp_info_head;
#pragma pack(4)
int show_bmp(const char * pathname, int x0, int y0)
{
int fd = open(pathname, O_RDWR);
if(fd < 0)
{
perror("open bmp failed\n");
return -1;
}
bmp_file_head fhead;
bmp_info_head ihead;
read(fd, &fhead, sizeof(fhead));
read(fd, &ihead, sizeof(ihead));
int size = ihead.bit_height * ihead.bit_width * 3;
unsigned char * data = malloc(size);
read(fd, data, size);
unsigned char * p = data;
int i = 0;
int j = 0;
for(j = 0; j < ihead.bit_height; j++) // y
{
for(i = 0; i < ihead.bit_width; i++) // x
{
col c;
c.rgb.b = *p++;
c.rgb.g = *p++;
c.rgb.r = *p++;
draw_point(x0 + i, y0 + ihead.bit_height - j - 1, c);
}
}
free(data);
close(fd);
}
void draw_a_ascii_by_zimo (int x0, int y0, unsigned char *zimo, col f)
{
int x, y;
for (y = 0; y < 16; y++) {
unsigned char tmp = *zimo++;
for (x = 0; x < 8; x++) {
if (tmp & 0x80) {
draw_point (x0 + x, y0 + y, f);
}
tmp = tmp << 1;
}
}
}
extern unsigned char font_8x16[4096];
void draw_a_ascii (int x0, int y0, char ch, col f)
{
unsigned char *pzimo = (void *)(font_8x16 + (int)ch * 16UL);
draw_a_ascii_by_zimo(x0, y0, pzimo, f);
}
void draw_string ( char *str, int x0, int y0,col f)
{
int len = strlen(str);
int i;
for (i = 0; i < len; i++)
{
switch (*str)
{
case '\r':x0 = 0;break;
case '\n':x0 = 0;y0 += 16; break;
case '\t':break;
case '\b':break;
default:draw_a_ascii(x0, y0, *str, f);
x0 += 8;
str++;
break;
}
}
}
int main(int argc, const char *argv[])
{
//open
int fd = open("/dev/fb0", O_RDWR);
if(fd < 0)
{
perror("open fd failed:");
return fd;
}
//get_screen_info
int ret = ioctl(fd, FBIOGET_VSCREENINFO, &info);
if(ret < 0)
{
perror("ioctl failed:");
return ret;
}
printf("xres = %d yres = %d\n",
info.xres, info.yres);
printf("xres_virtual = %d yres_virtual = %d\n",
info.xres_virtual, info.yres_virtual);
printf("bits_per_pixel = %d\n", info.bits_per_pixel);
//mmap
unsigned long size = info.xres_virtual * info.yres_virtual * info.bits_per_pixel / 8;
p_fd = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
if(NULL == p_fd)
{
perror("mmap failed:");
return -3;
}
col c;
c.rgb.r = 0xff;
c.rgb.g = 0xff;
c.rgb.b = 0xff;
clr_bg();
col c1;
c1.l = 0;
c1.rgb.r = 0xff;
int fd1 = open("1.txt", O_RDWR);
char buf[1024] = {0};
read(fd1, buf, sizeof(buf));
draw_string(buf, 100, 300, c1);
close(fd1);
//munmap
munmap(p_fd, size);
//close
close(fd);
return 0;
}