|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
#!/usr/bin/env python3 # 海康威视R1+飞牛系统 - fb0帧缓冲1像素精准网格显示 # 适配fb0模式:376×960 | 32位色深 | STRIDE=1536 import os # ===================== FB0硬件参数(贴合驱动标准命名) ===================== FRAMEBUFFER_DEVICE = "/dev/fb0" # 帧缓冲设备路径 SCREEN_VISIBLE_WIDTH = 376 # 可视宽度(X轴:0~375)- 驱动mode定义 SCREEN_NOMINAL_HEIGHT = 960 # 标称高度(驱动mode定义的理论高度) SCREEN_MAX_VALID_ROW = 939 # 实际有效最大行号(Y轴:0~939)- 受STRIDE限制 PIXEL_BYTES = 4 # 像素字节数(32位色深=4字节 RGBA) FRAMEBUFFER_STRIDE = 1536 # 帧缓冲行步长(每行占用字节数,硬件对齐要求) CHUNK_WRITE_SIZE = 4096 # 分块写入大小(避免单次写入过大) # 像素颜色定义(贴合RGBA 8/16,8/8,8/0,0/0格式) COLOR_WHITE = b'\xff\xff\xff\xff' # 白色(1px线条) COLOR_BLACK = b'\x00' * PIXEL_BYTES # 黑色(底色) # 帧缓冲安全总字节数(计算结果固定:376×960×4=1443840) FRAMEBUFFER_SAFE_TOTAL_BYTES = 1443840 # ===================== 通用绘图函数 ===================== def draw_vertical_line(screen_buffer, x_coord): """ 绘制垂直1像素线条 :param screen_buffer: 帧缓冲字节数组 :param x_coord: 垂直线条的X坐标(需在0~375范围内) """ if not (0 <= x_coord < SCREEN_VISIBLE_WIDTH): return # 遍历所有实际有效行(0~939) for y_row in range(SCREEN_MAX_VALID_ROW + 1): # 计算像素偏移:行号×行步长 + X坐标×像素字节数 pixel_offset = y_row * FRAMEBUFFER_STRIDE + x_coord * PIXEL_BYTES # 确保偏移在安全字节范围内 if pixel_offset + PIXEL_BYTES <= FRAMEBUFFER_SAFE_TOTAL_BYTES: screen_buffer[pixel_offset:pixel_offset+PIXEL_BYTES] = COLOR_WHITE def draw_horizontal_line(screen_buffer, y_row): """ 绘制水平1像素线条 :param screen_buffer: 帧缓冲字节数组 :param y_row: 水平线条的Y行号(需在0~939范围内) """ if not (0 <= y_row <= SCREEN_MAX_VALID_ROW): return # 计算当前行起始偏移 line_start_offset = y_row * FRAMEBUFFER_STRIDE # 遍历所有可视列(0~375) for x_coord in range(SCREEN_VISIBLE_WIDTH): pixel_offset = line_start_offset + x_coord * PIXEL_BYTES if pixel_offset + PIXEL_BYTES <= FRAMEBUFFER_SAFE_TOTAL_BYTES: screen_buffer[pixel_offset:pixel_offset+PIXEL_BYTES] = COLOR_WHITE # ===================== 生成网格数据 ===================== def generate_grid_buffer(): """生成黑底白线条的网格帧缓冲数据""" # 初始化全屏黑色(安全字节范围内) screen_buffer = bytearray(FRAMEBUFFER_SAFE_TOTAL_BYTES) # 1. 绘制外边框(可视范围最外像素) draw_vertical_line(screen_buffer, 0) # 左边框 X=0 draw_vertical_line(screen_buffer, 375) # 右边框 X=375 draw_horizontal_line(screen_buffer, 0) # 上边框 Y=0 draw_horizontal_line(screen_buffer, SCREEN_MAX_VALID_ROW) # 下边框 Y=939 # 2. 绘制中间分割线(2竖3横) for x in [125, 251]: # 垂直分割线 draw_vertical_line(screen_buffer, x) for y in [240, 480, 720]: # 水平分割线 draw_horizontal_line(screen_buffer, y) return bytes(screen_buffer) # ===================== 写入帧缓冲 ===================== def write_grid_to_framebuffer(): """将网格数据分块写入fb0,确保稳定显示""" # 赋予帧缓冲设备可读写权限 os.system(f"chmod 666 {FRAMEBUFFER_DEVICE}") # 步骤1:清空屏幕(全屏黑色) print("🔄 清空屏幕,初始化黑色底色...") with open(FRAMEBUFFER_DEVICE, 'wb') as fb_fd: remaining_bytes = FRAMEBUFFER_SAFE_TOTAL_BYTES while remaining_bytes > 0: write_bytes = min(CHUNK_WRITE_SIZE, remaining_bytes) fb_fd.write(COLOR_BLACK * (write_bytes // PIXEL_BYTES)) remaining_bytes -= write_bytes os.sync() # 强制刷入硬件 # 步骤2:生成并写入网格数据 print("🔄 写入1像素精准网格(适配fb0 376×960模式)...") grid_data = generate_grid_buffer() with open(FRAMEBUFFER_DEVICE, 'wb') as fb_fd: offset = 0 total_bytes = len(grid_data) while offset < total_bytes: write_bytes = min(CHUNK_WRITE_SIZE, total_bytes - offset) fb_fd.write(grid_data[offset:offset+write_bytes]) offset += write_bytes os.sync() # 完成提示(贴合实际参数) print("\n✅ 网格绘制完成!") print("📌 适配参数:") print(f" - fb0模式:376×960(标称) | 实际有效行:0~{SCREEN_MAX_VALID_ROW}") print(f" - 像素格式:32位RGBA({PIXEL_BYTES}字节/像素) | 行步长:{FRAMEBUFFER_STRIDE}字节") print(" - 线条规格:1像素宽度,外边框精准贴合可视范围最外像素") # ===================== 程序入口 ===================== if __name__ == "__main__": write_grid_to_framebuffer() |
发表回复