draw_hollow.h

  name="google_ads_frame" marginwidth="0" marginheight="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-5572165936844014&dt=1194442938015&lmt=1194190197&format=336x280_as&output=html&correlator=1194442937843&url=file%3A%2F%2F%2FC%3A%2FDocuments%2520and%2520Settings%2Flhh1%2F%E6%A1%8C%E9%9D%A2%2FCLanguage.htm&color_bg=FFFFFF&color_text=000000&color_link=000000&color_url=FFFFFF&color_border=FFFFFF&ad_type=text&ga_vid=583001034.1194442938&ga_sid=1194442938&ga_hid=1942779085&flash=9&u_h=768&u_w=1024&u_ah=740&u_aw=1024&u_cd=32&u_tz=480&u_java=true" frameborder="0" width="336" scrolling="no" height="280" allowtransparency="allowtransparency"> #define IDM_EXIT           100
#define IDM_TEST           200
#define IDM_ABOUT          301

LRESULT CALLBACK WndProc  (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About    (HWND, UINT, WPARAM, LPARAM);

#include <stdio.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" #include "driver/spi_master.h" #include "driver/gpio.h" // OLED 屏幕参数 (128x64) #define OLED_WIDTH 128 #define OLED_HEIGHT 64 #define PAGE_SIZE (OLED_WIDTH * OLED_HEIGHT / 8) // SPI 设置 #define PIN_NUM_MOSI 17 #define PIN_NUM_CLK 4 #define PIN_NUM_CS 19 #define PIN_NUM_DC 18 #define PIN_NUM_RST 5 spi_device_handle_t spi; // 帧缓冲区(每字节表示8行的1列像素) uint8_t oled_buffer[PAGE_SIZE] = {0}; // 发送命令或数据 void oled_write_cmd(uint8_t cmd) { gpio_set_level(PIN_NUM_DC, 0); // 命令模式 spi_transaction_t t = { .tx_buffer = &cmd, .length = 8 }; spi_device_transmit(spi, &t); } void oled_write_data(uint8_t *data, size_t len) { gpio_set_level(PIN_NUM_DC, 1); // 数据模式 spi_transaction_t t = { .tx_buffer = data, .length = len * 8 }; spi_device_transmit(spi, &t); } // 初始化 OLED (SSD1306) void oled_init() { oled_write_cmd(0xAE); // 关闭显示 oled_write_cmd(0xD5); oled_write_cmd(0x80); // 时钟分频 oled_write_cmd(0xA8); oled_write_cmd(0x3F); // 多路复用比=63 oled_write_cmd(0xD3); oled_write_cmd(0x00); // 偏移 oled_write_cmd(0x40); // 起始行 oled_write_cmd(0x8D); oled_write_cmd(0x14); // 充电泵开启 oled_write_cmd(0x20); oled_write_cmd(0x00); // 水平寻址模式 oled_write_cmd(0xA1); // 段重映射 oled_write_cmd(0xC8); // COM输出扫描方向 oled_write_cmd(0xDA); oled_write_cmd(0x12); // COM引脚配置 oled_write_cmd(0x81); oled_write_cmd(0xCF); // 对比度 oled_write_cmd(0xD9); oled_write_cmd(0xF1); // 预充电周期 oled_write_cmd(0xDB); oled_write_cmd(0x40); // VCOMH电平 oled_write_cmd(0xA4); // 正常显示 oled_write_cmd(0xA6); // 非反色 oled_write_cmd(0xAF); // 开启显示 } // 设置像素点 (x,y),v=1点亮 void oled_draw_pixel(int x, int y, int v) { if (x < 0 || x >= OLED_WIDTH || y < 0 || y >= OLED_HEIGHT) return; int page = y / 8; int bit = y % 8; int idx = page * OLED_WIDTH + x; if (v) oled_buffer[idx] |= (1 << bit); else oled_buffer[idx] &= ~(1 << bit); } // 绘制空心矩形(边框为1像素宽) void draw_hollow_rect(int x0, int y0, int w, int h) { int x1 = x0 + w - 1; int y1 = y0 + h - 1; for (int x = x0; x <= x1; x++) { oled_draw_pixel(x, y0, 1); // 上边 oled_draw_pixel(x, y1, 1); // 下边 } for (int y = y0; y <= y1; y++) { oled_draw_pixel(x0, y, 1); // 左边 oled_draw_pixel(x1, y, 1); // 右边 } } // 刷新缓冲区到屏幕 void oled_refresh() { for (int page = 0; page < 8; page++) { oled_write_cmd(0xB0 + page); // 设置页地址 oled_write_cmd(0x00); // 列低位 oled_write_cmd(0x10); // 列高位 oled_write_data(&oled_buffer[page * OLED_WIDTH], OLED_WIDTH); } } void app_main() { // 初始化 SPI 总线 spi_bus_config_t buscfg = { .mosi_io_num = PIN_NUM_MOSI, .miso_io_num = -1, .sclk_io_num = PIN_NUM_CLK, .quadwp_io_num = -1, .quadhd_io_num = -1, .max_transfer_sz = 32 }; spi_device_interface_config_t devcfg = { .clock_speed_hz = 8000000, .mode = 0, .spics_io_num = PIN_NUM_CS, .queue_size = 1, }; spi_bus_initialize(HSPI_HOST, &buscfg, 1); spi_bus_add_device(HSPI_HOST, &devcfg, &spi); // 配置 DC 和 RST 引脚 gpio_set_direction(PIN_NUM_DC, GPIO_MODE_OUTPUT); gpio_set_direction(PIN_NUM_RST, GPIO_MODE_OUTPUT); // 复位 OLED gpio_set_level(PIN_NUM_RST, 0); vTaskDelay(10 / portTICK_PERIOD_MS); gpio_set_level(PIN_NUM_RST, 1); // 初始化 OLED oled_init(); // 清屏 for (int i = 0; i < PAGE_SIZE; i++) oled_buffer[i] = 0; // 绘制一个居中的空心矩形 (例如:40x30) draw_hollow_rect(44, 17, 40, 30); // (x,y,width,height) // 刷新显示 oled_refresh(); while (1) { vTaskDelay(1000 / portTICK_PERIOD_MS); } } 那些数据决定了这个oled显示的是个空心矩形,逻辑原理是怎样的
10-20
import cv2 import imageio import numpy as np from PIL import Image, ImageDraw, ImageFont import os import pandas as pd import tqdm def read_gif(gif_path): try: # 使用 imageio 读取 GIF 文件 gif = imageio.get_reader(gif_path) # 只需要获取第一帧就行了 frame = gif.get_data(0) # 将 imageio 读取的帧转换为 OpenCV 可以处理的 BGR 格式 frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) # 直接裁剪指定区域 x, y, w, h = 438, 61, 282, 282 cropped = frame[y:y + h, x:x + w] # cv2.imshow("info",cropped) # cv2.waitKey(0) # 处理裁剪后的图像 cropped_gray = cv2.cvtColor(cropped, cv2.COLOR_BGR2GRAY) _, cropped_thresh = cv2.threshold(cropped_gray, 127, 255, cv2.THRESH_BINARY) # 使用 RETR_TREE 模式查找轮廓,获取层级信息 cropped_contours, cropped_hierarchy = cv2.findContours(cropped_thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) result_text = "未检测到图形,\n视为错误。" text_color = (0, 0, 255) # 默认红色 has_hollow_contour = False # 标记是否检测到空心轮廓 if len(cropped_contours) > 0: for i, contour in enumerate(cropped_contours): # 检查是否存在子轮廓(即是否为空心) if cropped_hierarchy[0][i][2] != -1: has_hollow_contour = True result_text = "检测到空心轮廓,\n视为正确。" text_color = (0, 255, 0) # 绿色 # 绘制外部轮廓 cv2.drawContours(cropped, [contour], -1, text_color, 2) # 绘制内部空心轮廓 child_index = cropped_hierarchy[0][i][2] while child_index != -1: cv2.drawContours(cropped, [cropped_contours[child_index]], -1, text_color, 2) # 绿色绘制内部轮廓 child_index = cropped_hierarchy[0][child_index][0] # 如果没有检测到空心轮廓,则视为检测到实心轮廓 if not has_hollow_contour: result_text = "检测到实心或不封闭轮廓,\n视为错误。" text_color = (0, 0, 255) # 红色 largest_contour = max(cropped_contours, key=cv2.contourArea) cv2.drawContours(cropped, [largest_contour], -1, text_color, 2) # 使用 PIL 显示中文 cropped_pil = Image.fromarray(cv2.cvtColor(cropped, cv2.COLOR_BGR2RGB)) draw = ImageDraw.Draw(cropped_pil) # 需要根据实际情况替换字体文件路径 font = ImageFont.truetype("simhei.ttf", 20) text_color_rgb = tuple(reversed(text_color)) # 转换 BGR 到 RGB draw.text((10, 30), result_text, font=font, fill=text_color_rgb) cropped = cv2.cvtColor(np.array(cropped_pil), cv2.COLOR_RGB2BGR) # 显示裁剪后的图片 cv2.imshow('Cropped Largest Rectangle', cropped) cv2.waitKey(100) # 若结果包含错误信息,视为检测到错误 if "错误" in result_text: return True else: return False except Exception as e: print(f"处理 {gif_path} 时出错: {e}") return True def main(): # 定义四个大文件夹路径 parent_folders = ["A12_1", "A12_2", "A13_1", "A13_2"] error_data = [] gif_files = [] # 收集所有 GIF 文件路径 for parent_folder in parent_folders: for root, dirs, files in os.walk(parent_folder): for file in files: if file.lower().endswith('.gif'): gif_files.append(os.path.join(root, file)) # 使用 tqdm 显示进度条 for gif_path in tqdm.tqdm(gif_files, desc="处理 GIF 文件", unit="个"): is_error = read_gif(gif_path) if is_error: error_data.append({ "编号": os.path.basename(os.path.dirname(gif_path)), "所属大文件夹": next((folder for folder in parent_folders if folder in gif_path), "未知"), "错误图像文件路径": gif_path }) # 关闭opencv窗口 cv2.destroyAllWindows() # 将错误数据保存到 Excel if error_data: df = pd.DataFrame(error_data) df.to_excel("error_images.xlsx", index=False) print("错误图片信息已保存到 error_images.xlsx") else: print("未检测到错误图片") if __name__ == "__main__": main() ————这是一个识别图像的代码,我是一名初学者,请详细为我解释,并且告诉我怎么使用这个代码
06-25
#include "AmbaTypes.h" #include "AmbaPrint.h" #include "AmbaUtility.h" #include "AmbaMisraFix.h" #include "AmbaKAL.h" #include "LvglTest.h" #include "lvgl.h" #include "gui/lvgl_img_resource.h" #include "gui/language/lvgl_third_language.h" #include <string.h> #define LVGL_OK (0x00000000U) /* OK */ #define LVGL_NG (0x00000001U) /* NG */ #define SVC_OSD_BUF_NUM (1U) #define LVGL_LOG "LVGL" #define LOG_BUF_SIZE 512U #define LOG_ARGC 3U typedef struct { UINT32 width; UINT32 height; } Lvgl_size; static Lvgl_size Vout_Res[2]; static UINT32 MemShort = 0U; static UINT32 isInitial = 1U; // display static lv_disp_t *g_disp[2][SVC_OSD_BUF_NUM]; static UINT32 g_disp_count[2] = {0U, 0U}; /* store OSD framebuffer base for flush */ static UINT8 *g_osd_fb[2][SVC_OSD_BUF_NUM] = {0}; static lv_style_t rect_style; static lv_style_t solid_style; static lv_style_t fontStyle_ExtraSmall; static lv_style_t fontStyle_Small; static lv_style_t fontStyle_Big; static lv_style_t style_line; static lv_style_t background_object_style; lv_obj_t *label1; lv_obj_t *label2; lv_obj_t *btn1; lv_obj_t *btn2; lv_obj_t *label3; UINT8 UpdateFlag = 0U; static UINT32 LvglTest_InternalTaskCreate(void); static void *LvglTest_TimerHandleEntry(void *EntryArg); static void *LvglTest_tick(void *EntryArg); static void LvglTest_InternalLog(const char *buf); static void LvglTest_MemShortCB(void); static void LvglTest_LogOK(const char *pModule, const char *pFormat, UINT32 Arg1, UINT32 Arg2); static void LvglTest_LogNG(const char *pModule, const char *pFormat, UINT32 Arg1, UINT32 Arg2); static void LvglTest_disp_flush_VoutA(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p); static void LvglTest_disp_flush_VoutB(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p); static void LvglTest_SetStyle(void); static void LvglTest_my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data); static void LvglTest_example_btn(void); static void Lvgltest_displayer_driver_rounder_callback(lv_disp_drv_t *disp_drv, lv_area_t *area); static void LvglTest_btn3TimeChangeFunc(void); extern void TouchCtrlPoint_get(UINT16 *x, UINT16 *y, UINT8 *pressed); UINT32 LvglTest_Init(UINT32 VoutID, UINT8 **OsdBuf, UINT32 OsdWidth, UINT32 OsdHeight) { UINT32 RetVal = LVGL_OK, i; static UINT32 lv_initialized = 0U; static lv_disp_draw_buf_t disp_buf[2][SVC_OSD_BUF_NUM]; static lv_disp_drv_t disp_drv[2][SVC_OSD_BUF_NUM]; /*Descriptor of a display driver*/ lv_mem_monitor_t monitor; Vout_Res[VoutID].width = OsdWidth; Vout_Res[VoutID].height = OsdHeight; if (lv_initialized == 0U) { lv_init(); lv_mem_monitor(&monitor); gui_handler_init(); RetVal = LvglTest_InternalTaskCreate(); if (RetVal == LVGL_OK) { LvglTest_SetStyle(); lv_initialized = 1U; g_disp_count[VoutID] = i; /* record last index for this VoutID */ } lv_log_register_print_cb(LvglTest_InternalLog); /* Register print function for internal logs */ // lv_mem_hookCB(LvglTest_MemShortCB); AmbaMisra_TouchUnused(&LvglTest_MemShortCB); LvglTest_LogOK(LVGL_LOG, "Total LVGL memory size:[0x%X], FreeSize:[0x%X]", monitor.total_size, monitor.free_size); } if (RetVal == LVGL_OK) { UINT32 addr; for (i = 0; i < SVC_OSD_BUF_NUM; i++) { AmbaMisra_TypeCast(&addr, &OsdBuf[i]); lv_disp_draw_buf_init(&disp_buf[VoutID][i], OsdBuf[i], NULL, Vout_Res[VoutID].width * Vout_Res[VoutID].height); /* keep a copy of framebuffer base for flush */ g_osd_fb[VoutID][i] = OsdBuf[i]; lv_disp_drv_init(&disp_drv[VoutID][i]); /*Basic initialization*/ if (VoutID == 0U) { disp_drv[VoutID][i].flush_cb = LvglTest_disp_flush_VoutA; /*Set your driver function*/ } else if (VoutID == 1U) { disp_drv[VoutID][i].flush_cb = LvglTest_disp_flush_VoutB; /*Set your driver function*/ } disp_drv[VoutID][i].draw_buf = &disp_buf[VoutID][i]; /*Assign the buffer to the display*/ /* Keep physical buffer layout: 440x1920. Rotation is handled via lv_disp_set_rotation(). */ disp_drv[VoutID][i].hor_res = Vout_Res[VoutID].width; disp_drv[VoutID][i].ver_res = Vout_Res[VoutID].height; disp_drv[VoutID][i].rounder_cb = Lvgltest_displayer_driver_rounder_callback; (void)Lvgltest_displayer_driver_rounder_callback; /* enable software rotation so LVGL provides rotated area via color_p */ disp_drv[VoutID][i] .sw_rotate = 1U; disp_drv[VoutID][i].rotated = LV_DISP_ROT_90; // 旋转90度 disp_drv[VoutID][i].screen_transp = 1U; g_disp[VoutID][i] = lv_disp_drv_register(&disp_drv[VoutID][i]); /*Finally register the driver*/ /* Default keep 0/90 rotation as previously configured by caller; do not force here */ } /*Initialize the (dummy) input device driver*/ static lv_indev_drv_t indev_drv; lv_indev_drv_init(&indev_drv); indev_drv.type = LV_INDEV_TYPE_POINTER; indev_drv.read_cb = LvglTest_my_touchpad_read; lv_indev_drv_register(&indev_drv); AmbaMisra_TouchUnused(&LvglTest_my_touchpad_read); isInitial = 1U; for (i = 0; i < SVC_OSD_BUF_NUM; i++) { // lv_obj_set_style_bg_opa(lv_disp_get_scr_act(g_disp[VoutID][i]), 0, LV_PART_MAIN); } // LvglTest_example_btn(); AmbaMisra_TouchUnused(&LvglTest_example_btn); // lv_theme_default_init(NULL, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), false, LV_FONT_DEFAULT); for (i = 0; i < SVC_OSD_BUF_NUM; i++) { lv_refr_now(g_disp[VoutID][i]); } isInitial = 0U; LvglTest_LogOK(LVGL_LOG, "Finish Initial Vout:[%u]", VoutID, 0U); LvglTest_LogOK(LVGL_LOG, "Width:[%u], Height:[%u]", Vout_Res[VoutID].width, Vout_Res[VoutID].height); } // LvglTest_SetUiRotation(0, 270); ui_main_init(); return RetVal; } static UINT32 LvglTest_InternalTaskCreate(void) { UINT32 RetVal = LVGL_OK; static AMBA_KAL_TASK_t Lvgl_TickTask; static UINT8 LvTaskStack[0x10000U] GNU_SECTION_NOZEROINIT; static char LvglTickTaskName[16] = "LvglTick"; static AMBA_KAL_TASK_t Lvgl_TimeHandlerTask; static UINT8 LvTimeHandlerTaskStack[0x10000U] GNU_SECTION_NOZEROINIT; static char LvglTimeHandlerTaskName[16] = "LvglTimeHandler"; RetVal = AmbaKAL_TaskCreate(&Lvgl_TickTask, LvglTickTaskName, 43U, LvglTest_tick, 0U, LvTaskStack, 0x10000U, 0U); if (KAL_ERR_NONE == RetVal) { RetVal = AmbaKAL_TaskSetSmpAffinity(&Lvgl_TickTask, 0x02U); if (KAL_ERR_NONE == RetVal) { RetVal = AmbaKAL_TaskResume(&Lvgl_TickTask); } } RetVal = AmbaKAL_TaskCreate(&Lvgl_TimeHandlerTask, LvglTimeHandlerTaskName, 80U, LvglTest_TimerHandleEntry, 0U, LvTimeHandlerTaskStack, 0x10000U, 0U); if (KAL_ERR_NONE == RetVal) { RetVal = AmbaKAL_TaskSetSmpAffinity(&Lvgl_TimeHandlerTask, 0x02U); if (KAL_ERR_NONE == RetVal) { RetVal = AmbaKAL_TaskResume(&Lvgl_TimeHandlerTask); } } return RetVal; } static void *LvglTest_TimerHandleEntry(void *EntryArg) { (void)EntryArg; while (1) { gui_handler_entry(); lv_timer_handler(); // LvglTest_btn3TimeChangeFunc(); AmbaMisra_TouchUnused(&LvglTest_btn3TimeChangeFunc); } return NULL; } static void *LvglTest_tick(void *EntryArg) { (void)EntryArg; while (1) { lv_tick_inc(1U); AmbaKAL_TaskSleep(1U); } return NULL; } static void LvglTest_InternalLog(const char *buf) { AmbaPrint_PrintStr5("\033" "[0;31m[LVGL_Internal]%s", buf, NULL, NULL, NULL, NULL); AmbaPrint_Flush(); } static void LvglTest_LogOK(const char *pModule, const char *pFormat, UINT32 Arg1, UINT32 Arg2) { char LogBuf[LOG_BUF_SIZE]; const char *ArgS[LOG_ARGC]; UINT32 RetVal, Argc; Argc = 0; ArgS[Argc] = pModule; Argc++; ArgS[Argc] = pFormat; Argc++; RetVal = AmbaUtility_StringPrintStr(LogBuf, LOG_BUF_SIZE, "[%s|OK]: %s", Argc, ArgS); if (RetVal < LOG_BUF_SIZE) { AmbaPrint_PrintUInt5(LogBuf, Arg1, Arg2, 0U, 0U, 0U); } } static void LvglTest_LogNG(const char *pModule, const char *pFormat, UINT32 Arg1, UINT32 Arg2) { char LogBuf[LOG_BUF_SIZE]; const char *ArgS[LOG_ARGC]; UINT32 RetVal, Argc; Argc = 0; ArgS[Argc] = pModule; Argc++; ArgS[Argc] = pFormat; Argc++; RetVal = AmbaUtility_StringPrintStr(LogBuf, LOG_BUF_SIZE, "\033" "[0;31m[%s|NG]: %s", Argc, ArgS); if (RetVal < LOG_BUF_SIZE) { AmbaPrint_PrintUInt5(LogBuf, Arg1, Arg2, 0U, 0U, 0U); AmbaPrint_Flush(); } } static void LvglTest_MemShortCB(void) { MemShort = 1U; LvglTest_LogNG(LVGL_LOG, "Memory is not enough, consider increase CONFIG_SVC_LVGL_MEM", 0U, 0U); } /* 修改后的显示刷新函数,支持旋转 */ // static void LvglTest_disp_flush_VoutA(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) // { // if (isInitial == 1U) { // lv_disp_flush_ready(disp_drv); // return; // } // const UINT32 fb_width = Vout_Res[0].width; // const UINT32 fb_height = Vout_Res[0].height; // UINT8 *fb_base = g_osd_fb[0][0]; // UINT32 px_size = sizeof(lv_color_t); // /* 根据旋转角度处理像素数据 */ // switch (disp_drv->rotated) { // case LV_DISP_ROT_90: { // /* 正确的90度旋转算法 */ // UINT32 area_width = (UINT32)(area->x2 - area->x1 + 1); // UINT32 area_height = (UINT32)(area->y2 - area->y1 + 1); // for (UINT32 src_y = 0; src_y < area_height; src_y++) { // for (UINT32 src_x = 0; src_x < area_width; src_x++) { // /* 计算源缓冲区中的像素索引 */ // UINT32 src_index = src_y * area_width + src_x; // /* 计算旋转后的坐标 */ // // 90度顺时针旋转: (x, y) -> (y, width-1-x) // UINT32 dst_x = (UINT32)area->y1 + src_y; // UINT32 dst_y = fb_width - 1 - ((UINT32)area->x1 + src_x); // /* 确保坐标在有效范围内 */ // if (dst_x < fb_height && dst_y < fb_width) { // UINT8 *dst = fb_base + (dst_y * fb_width + dst_x) * px_size; // UINT8 *src = (UINT8 *)(color_p + src_index); // (void)memcpy(dst, src, px_size); // } // } // } // break; // } // case LV_DISP_ROT_270: { // /* 270度旋转 */ // UINT32 area_width = (UINT32)(area->x2 - area->x1 + 1); // UINT32 area_height = (UINT32)(area->y2 - area->y1 + 1); // for (UINT32 src_y = 0; src_y < area_height; src_y++) { // for (UINT32 src_x = 0; src_x < area_width; src_x++) { // UINT32 src_index = src_y * area_width + src_x; // /* 270度顺时针旋转: (x, y) -> (height-1-y, x) */ // UINT32 dst_x = fb_height - 1 - ((UINT32)area->y1 + src_y); // UINT32 dst_y = (UINT32)area->x1 + src_x; // if (dst_x < fb_height && dst_y < fb_width) { // UINT8 *dst = fb_base + (dst_y * fb_width + dst_x) * px_size; // UINT8 *src = (UINT8 *)(color_p + src_index); // (void)memcpy(dst, src, px_size); // } // } // } // break; // } // case LV_DISP_ROT_180: { // /* 180度旋转:上下左右完全翻转 */ // UINT32 area_w = (UINT32)(area->x2 - area->x1 + 1); // UINT32 area_h = (UINT32)(area->y2 - area->y1 + 1); // for (UINT32 src_y = 0; src_y < area_h; src_y++) { // UINT32 dst_y = fb_height - 1 - ((UINT32)area->y1 + src_y); // for (UINT32 src_x = 0; src_x < area_w; src_x++) { // UINT32 dst_x = fb_width - 1 - ((UINT32)area->x1 + src_x); // UINT8 *dst = fb_base + (dst_y * fb_width + dst_x) * px_size; // (void)memcpy(dst, color_p, px_size); // color_p++; // } // break; // } // break; // } // case LV_DISP_ROT_NONE: // default: { // /* 无旋转:直接复制 */ // UINT32 area_w = (UINT32)(area->x2 - area->x1 + 1); // for (UINT32 y = (UINT32)area->y1; y <= (UINT32)area->y2; y++) { // UINT8 *dst = fb_base + (y * fb_width + (UINT32)area->x1) * px_size; // UINT8 *src = (UINT8 *)(color_p + (y - (UINT32)area->y1) * area_w); // (void)memcpy(dst, src, area_w * px_size); // } // break; // } // } // lv_disp_flush_ready(disp_drv); // } static void LvglTest_disp_flush_VoutA(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) { if (isInitial == 1U) { lv_disp_flush_ready(disp_drv); return; } const UINT32 fb_width = Vout_Res[0].width; const UINT32 fb_height = Vout_Res[0].height; UINT8 *fb_base = g_osd_fb[0][0]; UINT32 px_size = sizeof(lv_color_t); /* 根据旋转角度处理像素数据 */ switch (disp_drv->rotated) { case LV_DISP_ROT_90: { /* 修正的90度顺时针旋转算法 */ const UINT32 fb_width = Vout_Res[0].width; UINT32 y; UINT8 *fb_base = g_osd_fb[0][0]; UINT32 px_size = sizeof(lv_color_t); UINT32 area_w = (UINT32)(area->x2 - area->x1 + 1); for (y = (UINT32)area->y1; y <= (UINT32)area->y2; y++) { UINT8 *dst = fb_base + ((UINT32)y * fb_width + (UINT32)area->x1) * px_size; (void)memcpy(dst, color_p, area_w * px_size); color_p += area_w; } break; } case LV_DISP_ROT_270: { /* 270度顺时针旋转 */ const UINT32 fb_width = Vout_Res[0].width; UINT32 y; UINT8 *fb_base = g_osd_fb[0][0]; UINT32 px_size = sizeof(lv_color_t); UINT32 area_w = (UINT32)(area->x2 - area->x1 + 1); for (y = (UINT32)area->y1; y <= (UINT32)area->y2; y++) { UINT8 *dst = fb_base + ((UINT32)y * fb_width + (UINT32)area->x1) * px_size; (void)memcpy(dst, color_p, area_w * px_size); color_p += area_w; } break; } case LV_DISP_ROT_180: { /* 180度旋转:上下左右完全翻转 */ UINT32 area_w = (UINT32)(area->x2 - area->x1 + 1); UINT32 area_h = (UINT32)(area->y2 - area->y1 + 1); for (UINT32 src_y = 0; src_y < area_h; src_y++) { UINT32 dst_y = fb_height - 1 - ((UINT32)area->y1 + src_y); for (UINT32 src_x = 0; src_x < area_w; src_x++) { UINT32 dst_x = fb_width - 1 - ((UINT32)area->x1 + src_x); UINT8 *dst = fb_base + (dst_y * fb_width + dst_x) * px_size; (void)memcpy(dst, color_p, px_size); color_p++; } break; } break; } case LV_DISP_ROT_NONE: default: { /* 无旋转:直接复制 */ UINT32 area_width = (UINT32)(area->x2 - area->x1 + 1); for (UINT32 y = (UINT32)area->y1; y <= (UINT32)area->y2; y++) { UINT8 *dst = fb_base + (y * fb_width + (UINT32)area->x1) * px_size; UINT8 *src = (UINT8 *)(color_p + (y - (UINT32)area->y1) * area_width); (void)memcpy(dst, src, area_width * px_size); } break; } } lv_disp_flush_ready(disp_drv); } static void Lvgltest_displayer_driver_rounder_callback(lv_disp_drv_t *disp_drv, lv_area_t *area) { // 根据旋转状态设置正确的分辨率 if (disp_drv->rotated == LV_DISP_ROT_90 || disp_drv->rotated == LV_DISP_ROT_270) { // 旋转后,水平分辨率变成原来的垂直分辨率,垂直分辨率变成原来的水平分辨率 area->x1 = 0; area->x2 = disp_drv->ver_res - 1; // 使用垂直分辨率作为宽度 area->y1 = 0; area->y2 = disp_drv->hor_res - 1; // 使用水平分辨率作为高度 } else { area->x1 = 0; area->x2 = disp_drv->hor_res - 1; area->y1 = 0; area->y2 = disp_drv->ver_res - 1; } } static void LvglTest_disp_flush_VoutB(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) { if (isInitial == 1U) { lv_disp_flush_ready(disp_drv); return; } const UINT32 fb_width = Vout_Res[1].width; const UINT32 fb_height = Vout_Res[1].height; UINT8 *fb_base = g_osd_fb[1][0]; UINT32 px_size = sizeof(lv_color_t); /* 根据旋转角度处理像素数据 */ switch (disp_drv->rotated) { case LV_DISP_ROT_90: { /* 90度旋转 */ for (UINT32 y = (UINT32)area->y1; y <= (UINT32)area->y2; y++) { for (UINT32 x = (UINT32)area->x1; x <= (UINT32)area->x2; x++) { UINT32 dst_x = fb_height - 1 - y; UINT32 dst_y = x; UINT8 *dst = fb_base + (dst_y * fb_width + dst_x) * px_size; (void)memcpy(dst, color_p, px_size); color_p++; } } break; } case LV_DISP_ROT_270: { /* 270度旋转 */ for (UINT32 y = (UINT32)area->y1; y <= (UINT32)area->y2; y++) { for (UINT32 x = (UINT32)area->x1; x <= (UINT32)area->x2; x++) { UINT32 dst_x = fb_height - 1 - y; UINT32 dst_y = x; UINT8 *dst = fb_base + (dst_y * fb_width + dst_x) * px_size; (void)memcpy(dst, color_p, px_size); color_p++; } } break; } case LV_DISP_ROT_180: { /* 180度旋转 */ for (UINT32 y = (UINT32)area->y1; y <= (UINT32)area->y2; y++) { for (UINT32 x = (UINT32)area->x1; x <= (UINT32)area->x2; x++) { UINT32 dst_x = fb_width - 1 - x; UINT32 dst_y = fb_height - 1 - y; UINT8 *dst = fb_base + (dst_y * fb_width + dst_x) * px_size; (void)memcpy(dst, color_p, px_size); color_p++; } } break; } case LV_DISP_ROT_NONE: default: { /* 无旋转:直接复制 */ UINT32 area_w = (UINT32)(area->x2 - area->x1 + 1); for (UINT32 y = (UINT32)area->y1; y <= (UINT32)area->y2; y++) { UINT8 *dst = fb_base + (y * fb_width + (UINT32)area->x1) * px_size; (void)memcpy(dst, color_p, area_w * px_size); color_p += area_w; } break; } } lv_disp_flush_ready(disp_drv); } static void LvglTest_SetStyle(void) { #define LV_COLOR_BLUE ((lv_color_t){{0x00, 0x00, 0xFF, 0xFF}}) // Hollow Rectangle Style lv_style_init(&rect_style); lv_style_set_bg_opa(&rect_style, LV_OPA_40); lv_style_set_radius(&rect_style, 0); lv_style_set_border_color(&rect_style, LV_COLOR_BLUE); lv_style_set_border_width(&rect_style, 6); // Small font px=10 lv_style_init(&fontStyle_ExtraSmall); // lv_style_set_text_font(&fontStyle_ExtraSmall, &lv_font_sans_10_Amba); // Small font px=14 lv_style_init(&fontStyle_Small); // lv_style_set_text_font(&fontStyle_Small, &lv_font_sans_14_Amba); // Big font px=30 lv_style_init(&fontStyle_Big); // lv_style_set_text_font(&fontStyle_Big, &lv_font_sans_30_Amba); // Soild Rectangle Style lv_style_init(&solid_style); lv_style_set_radius(&solid_style, 0); lv_style_set_border_opa(&solid_style, 0); // Line Style lv_style_init(&style_line); lv_style_set_line_width(&style_line, 8); lv_style_set_line_rounded(&style_line, true); // Parent style of each dispaly lv_style_init(&background_object_style); lv_style_set_border_opa(&background_object_style, 0); lv_style_set_bg_opa(&background_object_style, 0); } void LvglTest_SetBuffer(UINT32 VoutID, UINT32 BufId, UINT8 *BufAddr) { g_disp[VoutID][0U]->driver->draw_buf->buf1 = BufAddr; g_disp[VoutID][0U]->driver->draw_buf->buf_act = BufAddr; MemShort = 0U; (void)VoutID; (void)BufId; (void)BufAddr; } // static void Lvgltest_displayer_driver_rounder_callback(lv_disp_drv_t *disp_drv, lv_area_t *area) // { // area->x1 = 0; // area->x2 = disp_drv->hor_res - 1; // area->y1 = 0; // area->y2 = disp_drv->ver_res - 1; // // area->x1 = 0; // // area->x2 = disp_drv->ver_res - 1; // // area->y1 = 0; // // area->y2 = disp_drv->hor_res - 1; // } #if 0 /*Create an image button*/ lv_obj_t * imgbtn1; lv_obj_t * label; void LvglTest_example_imgbtn_1(void) { LV_IMG_DECLARE(imgbtn_left); LV_IMG_DECLARE(imgbtn_right); LV_IMG_DECLARE(imgbtn_mid); /*Create a transition animation on width transformation and recolor.*/ static lv_style_prop_t tr_prop[] = {LV_STYLE_TRANSFORM_WIDTH, LV_STYLE_IMG_RECOLOR_OPA, 0}; static lv_style_transition_dsc_t tr; lv_style_transition_dsc_init(&tr, tr_prop, lv_anim_path_linear, 200, 0, NULL); static lv_style_t style_def; lv_style_init(&style_def); lv_style_set_text_color(&style_def, lv_color_white()); lv_style_set_transition(&style_def, &tr); /*Darken the button when pressed and make it wider*/ static lv_style_t style_pr; lv_style_init(&style_pr); lv_style_set_img_recolor_opa(&style_pr, LV_OPA_30); lv_style_set_img_recolor(&style_pr, lv_color_black()); lv_style_set_transform_width(&style_pr, 20); /*Create an image button*/ imgbtn1 = lv_imgbtn_create(lv_scr_act()); lv_imgbtn_set_src(imgbtn1, LV_IMGBTN_STATE_RELEASED, &imgbtn_left, &imgbtn_mid, &imgbtn_right); lv_obj_add_style(imgbtn1, &style_def, 0); lv_obj_add_style(imgbtn1, &style_pr, LV_STATE_PRESSED); lv_obj_align(imgbtn1, LV_ALIGN_CENTER, 0, 0); /*Create a label on the image button*/ //lv_obj_t * label = lv_label_create(imgbtn1); label = lv_label_create(imgbtn1); lv_label_set_text(label, "Button"); lv_obj_align(label, LV_ALIGN_CENTER, 0, -4); } #endif static void LvglTest_my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) { UINT16 x, y; UINT8 pressed; AmbaMisra_TouchUnused(&indev_driver); TouchCtrlPoint_get(&x, &y, &pressed); if (!pressed) { data->state = LV_INDEV_STATE_REL; } else { data->state = LV_INDEV_STATE_PR; data->point.x = 440 - (lv_coord_t)y; data->point.y = (lv_coord_t)x; } } static void event_handler(lv_event_t *e) { static UINT8 flage = 0; lv_event_code_t code = lv_event_get_code(e); if (code == LV_EVENT_CLICKED) { // LV_LOG_USER("event_handler Clicked"); if (flage == 0) { flage = 1; lv_label_set_text(label1, "Cli_000"); } else { flage = 0; lv_label_set_text(label1, "Cli_111"); } LvglTest_SetUpdateFlag(); } else if (code == LV_EVENT_VALUE_CHANGED) { LV_LOG_USER("Toggled"); } } static void event_handler1(lv_event_t *e) { static UINT8 flage = 0; lv_event_code_t code = lv_event_get_code(e); if (code == LV_EVENT_CLICKED) { // LV_LOG_USER("event_handler1 Clicked"); if (flage == 0) { flage = 1; lv_label_set_text(label2, "To_000"); } else { flage = 0; lv_label_set_text(label2, "To_111"); } LvglTest_SetUpdateFlag(); } else if (code == LV_EVENT_VALUE_CHANGED) { } } static void LvglTest_example_btn(void) { btn1 = lv_btn_create(lv_scr_act()); lv_obj_add_event_cb(btn1, event_handler, LV_EVENT_ALL, NULL); lv_obj_set_x(btn1, 10); lv_obj_set_y(btn1, 50); lv_obj_add_style(btn1, &rect_style, 0); lv_obj_add_style(btn1, &solid_style, LV_STATE_PRESSED); label1 = lv_label_create(btn1); lv_label_set_text(label1, "Button"); lv_obj_center(label1); btn2 = lv_btn_create(lv_scr_act()); lv_obj_add_event_cb(btn2, event_handler1, LV_EVENT_ALL, NULL); lv_obj_set_x(btn2, 10); lv_obj_set_y(btn2, 100); lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE); lv_obj_set_height(btn2, LV_SIZE_CONTENT); lv_obj_add_style(btn2, &rect_style, 0); lv_obj_add_style(btn2, &solid_style, LV_STATE_PRESSED); label2 = lv_label_create(btn2); lv_label_set_text(label2, "Toggle"); lv_obj_center(label2); label3 = lv_label_create(lv_scr_act()); lv_label_set_text(label3, "00:00:00:"); lv_obj_set_x(label3, 100); lv_obj_set_y(label3, 150); // lv_obj_set_style_text_font(label3,&lv_font_sans_30_Amba, LV_PART_MAIN | LV_STATE_DEFAULT); } static void LvglTest_btn3TimeChangeFunc(void) { char timer[50]; static UINT32 data = 0; static UINT8 count = 0; count++; if (count == 20) { count = 0; data++; AmbaWrap_memset(timer, 0, 50); (void)AmbaUtility_StringPrintUInt32(timer, 32, "00:00:00:%d", 1, &data); if (data >= 999U) { data = 0; } lv_label_set_text(label3, timer); LvglTest_SetUpdateFlag(); } } void LvglTest_SetUpdateFlag(void) { UpdateFlag = 0U; } UINT8 LvglTest_GetUpdateFlag(void) { return UpdateFlag; } void LvglTest_ResetUpdateFlag(void) { UpdateFlag = 0U; } void LvglTest_refr_now(UINT32 VoutID) { UINT8 i = 0; for (i = 0; i < SVC_OSD_BUF_NUM; i++) { lv_refr_now(g_disp[VoutID][i]); } } void LvglTest_SetUiRotation(UINT32 VoutID, UINT32 Degree) { lv_disp_rot_t rot = LV_DISP_ROT_NONE; if (Degree == 90U) { rot = LV_DISP_ROT_90; } else if (Degree == 180U) { rot = LV_DISP_ROT_180; } else if (Degree == 270U) { rot = LV_DISP_ROT_270; } else { rot = LV_DISP_ROT_NONE; } for (UINT32 i = 0U; i < SVC_OSD_BUF_NUM; i++) { if (g_disp[VoutID][i] != NULL) { lv_disp_set_rotation(g_disp[VoutID][i], rot); } } }该文件代码中,旋转90度时画面有噪点,修改优化
最新发布
10-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值