硬汉嵌入式论坛

 找回密码
 立即注册
查看: 784|回复: 6
收起左侧

[LVGL] LVGL读取外部flash后,一张图片分两次读取显示都是显示最后一半,怎么解决

[复制链接]

1

主题

3

回帖

6

积分

新手上路

积分
6
发表于 2024-12-2 16:12:26 | 显示全部楼层 |阅读模式
#include "ui.h"
#include "w25x40.h"
#define IMAGE_WIDTH    200    // 图像宽度
#define IMAGE_HEIGHT   200    // 图像高度
#define IMAGE_SIZE     (IMAGE_WIDTH * IMAGE_HEIGHT * 3)  // 总图像大小 (200 * 200 * 3 字节)
#define CHUNK_HEIGHT   100    // 每次读取 100 行
#define CHUNK_SIZE     (IMAGE_WIDTH * CHUNK_HEIGHT * LV_IMG_PX_SIZE_ALPHA_BYTE) // 每次读取的大小

#define IMAGE_ADDRESS  0x000004  // 外部Flash中图像的存储地址 (根据实际存储地址调整)

#ifndef LV_ATTRIBUTE_MEM_ALIGN
#define LV_ATTRIBUTE_MEM_ALIGN
#endif

#ifndef LV_ATTRIBUTE_IMG_FRAME
#define LV_ATTRIBUTE_IMG_FRAME
#endif
LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_FRAME uint8_t Frame_map[IMAGE_WIDTH * CHUNK_HEIGHT*LV_IMG_PX_SIZE_ALPHA_BYTE];

lv_img_dsc_t Frame = {
        .header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA,
        .header.always_zero = 0,
        .header.reserved = 0,
        .header.w = IMAGE_WIDTH,
        .header.h = CHUNK_HEIGHT,  // 每次显示一部分
        .data_size = CHUNK_SIZE,   // 每块数据大小
        .data = Frame_map,         // 当前块的数据
};
uint32_t offset;
void ui_Logo_screen_init(void)
{
    // 创建一个屏幕对象
    ui_Logo = lv_obj_create(NULL);
    lv_obj_clear_flag(ui_Logo, LV_OBJ_FLAG_SCROLLABLE);  // 清除滚动标志
    lv_obj_set_style_radius(ui_Logo, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_color(ui_Logo, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
    lv_obj_set_style_bg_opa(ui_Logo, 255, LV_PART_MAIN | LV_STATE_DEFAULT);

    // 读取并显示每个图像块
    for (int i = 0; i < IMAGE_WIDTH/CHUNK_HEIGHT; i++)
    {
        // 计算每次读取的地址偏移
        offset = IMAGE_ADDRESS + (i * IMAGE_WIDTH * CHUNK_HEIGHT * LV_IMG_PX_SIZE_ALPHA_BYTE);
        // 从 Flash 读取当前块的数据
        SPI_FLASH_BufferRead(Frame_map, offset, CHUNK_SIZE);
        //创建新的图像对象并显示每个图像块
        ui_LenovoLogo = lv_img_create(ui_Logo);
        lv_img_set_src(ui_LenovoLogo, &Frame);
        lv_obj_set_width(ui_LenovoLogo, IMAGE_WIDTH);      // 设置图像宽度
        lv_obj_set_height(ui_LenovoLogo, CHUNK_HEIGHT);    // 设置每块显示的高度
        lv_obj_set_align(ui_LenovoLogo, LV_ALIGN_TOP_MID); // 每块图像居中对齐
                                //在Y轴上设置当前块的显示位置
        lv_obj_set_y(ui_LenovoLogo, i * CHUNK_HEIGHT);  // 设置垂直位置
        lv_obj_clear_flag(ui_LenovoLogo, LV_OBJ_FLAG_HIDDEN);  // 确保图像显示
        lv_obj_set_style_opa(ui_LenovoLogo, 255, LV_PART_MAIN | LV_STATE_DEFAULT);              
    }
}


回复

使用道具 举报

1

主题

3

回帖

6

积分

新手上路

积分
6
 楼主| 发表于 2024-12-2 18:56:15 | 显示全部楼层
求助
回复

使用道具 举报

677

主题

3460

回帖

5516

积分

论坛元老

积分
5516
发表于 2024-12-3 09:23:30 | 显示全部楼层
本帖最后由 hpdell 于 2024-12-3 09:44 编辑

你有没有配 sdram ?

如果有的话可以一次性全部读取一幅完整的图片数据加载到 sdram , 然后再 显示出来的就可以了

还有 LV_IMG_CF_TRUE_COLOR_ALPHA 这个带透明通道的格式的吧 ?  如果你的图片不带 透明通道的,使用 LV_IMG_CF_TRUE_COLOR 试试看

只显示后一半,估计是前一半被覆盖掉了吧 ??

你吧 lv_obj_set_align(ui_LenovoLogo, LV_ALIGN_TOP_MID); // 每块图像居中对齐  这个对齐屏蔽试试看



回复

使用道具 举报

1

主题

3

回帖

6

积分

新手上路

积分
6
 楼主| 发表于 2024-12-3 16:34:15 | 显示全部楼层
hpdell 发表于 2024-12-3 09:23
你有没有配 sdram ?

如果有的话可以一次性全部读取一幅完整的图片数据加载到 sdram , 然后再 显示出 ...

图片是120kb的,我这个sram只有144kb,如果整一张读显示应该是没问题的,我是想分散出来显示的,不然太占内存了,我这个就是带透明度的,是被覆盖掉了,屏蔽了也一样,显示的都是最后读到数据的那一半,
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2025-2-10 17:02:04 | 显示全部楼层
楼主遇到的问题解决了吗?我也遇到了同样的问题
回复

使用道具 举报

24

主题

131

回帖

203

积分

高级会员

积分
203
发表于 2025-2-13 15:23:48 | 显示全部楼层
简单的。图片通过PC机进行预先分割为4张,MCU按4张图片处理
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-4-26 00:43 , Processed in 0.264979 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表