找回密码
 立即注册
查看: 57|回复: 1

虚拟开发板显示图片失真怎么解决?

[复制链接]

10

主题

4

回帖

44

积分

新手上路

积分
44
发表于 2023-2-2 16:53:28 | 显示全部楼层 |阅读模式


//显示一张800*480的图片
#include <stdio.h>
#include <dlfcn.h>  // 动态加载动态库的头文件:dlopen()、dlsym()
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>

#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/mman.h>

// BMP格式头规范
struct bitmap_header
{
        int16_t type;
        int32_t size; // 图像文件大小
        int16_t reserved1;
        int16_t reserved2;
        int32_t offbits; // bmp图像数据偏移量
}__attribute__((packed));

struct bitmap_info
{
        int32_t size;   // 本结构大小       
        int32_t width;  // 图像宽
        int32_t height; // 图像高
        int16_t planes;

        int16_t bit_count; // 色深
        int32_t compression;
        int32_t size_img; // bmp数据大小,必须是4的整数倍
        int32_t X_pel;
        int32_t Y_pel;
        int32_t clrused;
        int32_t clrImportant;
}__attribute__((packed));

// 以下结构体不一定存在于BMP文件中,除非:
// bitmap_info.compression为真
struct rgb_quad
{
        int8_t blue;
        int8_t green;
        int8_t red;
        int8_t reserved;
}__attribute__((packed));


#define FB_FILE  "/dev/fb0"

unsigned int *mem_p;

int lcd_fd;

int lcd_init(void);
int lcd_uninit(void);
int show_bmp(const char *pathname);

int main(void)
{
    lcd_init();
    show_bmp("a.bmp");

    lcd_uninit();
    return 0;
}


int lcd_init(void)
{
    //打开file.txt文件, 文件不存在,则打开失败,如果使用O_CREAT,那必须要添加文件权限。
    lcd_fd = open(FB_FILE, O_RDWR);
    if(lcd_fd == -1)
    {
        printf("open a.txt fail\n");
        return -1;
    }   

    //屏幕映射
    mem_p = (unsigned int *)mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);
    if(mem_p == MAP_FAILED)
    {
        printf("mmap fail\n");
    }

    return 0;
}
int lcd_uninit(void)
{
   // 解除映射
    munmap(mem_p, 800*480*4);
    close(lcd_fd);

}


int show_bmp(const char *pathname)
{
    int i, j, x, y;
    unsigned char bmpbuff[800*480*3] = {0};
    unsigned int buff[800*480] = {0};

        int bmp_fd = open(pathname, O_RDONLY);
    if(bmp_fd == -1)
    {
        printf("open bmp fail\n");
        return -1;
    }
    //跳过54个字节头
    lseek(bmp_fd, 54, SEEK_SET);

    read(bmp_fd, bmpbuff, sizeof(bmpbuff));

    for(i=0; i<800*480; i++)
    {
        //buff[0] = bmpbuff[0]<<16 | bmpbuff[1]<<8 | bmpbuff[2];
        buff[i] = bmpbuff[3*i+0] | bmpbuff[3*i+1]<<8 | bmpbuff[3*i+2]<<16;
    }

//显示图片(倒置:反过来的)
    for(y=0; y<480; y++)
    {
        for(x=0; x<800; x++)
        {
            *(mem_p+y*800+x) = buff[y*800+x];
        }

    }

    close(bmp_fd);

    return 0;
}

回复

使用道具 举报

10

主题

4

回帖

44

积分

新手上路

积分
44
 楼主| 发表于 2023-2-2 16:55:13 | 显示全部楼层
在读取的时候加上unsigned,就可以保证数据完全读取成功。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|粤嵌技术交流空间

GMT+8, 2025-7-7 18:35 , Processed in 0.707470 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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