嵌入式开发板6818显示任意大小bmp图片。原码

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
    //目标:这份代码要能够显示任意大小的图片
    //第一步:打开 fb0 和 图片 文件

    int lcd = open("/dev/fb0",O_WRONLY);
    /*
    这是嵌入式开发板中根目录下的文件夹,fb0是显示屏的文件io,
    first.bmp需要你提前烧写进开发板中
    */
    int bmp = open("/first.bmp",O_RDONLY);
    if(lcd == -1 || bmp == -1)
    {
        printf("文件打开失败\n");
        return -1;
    }
    else
    {
        printf("文件打开成功\n");
    }

    //第二步:通过图片开头的54个字节,来获取图片的宽和图片的高
    int  buf_width;//图像的宽度
    int buf_heigh;//图像的高度
    int argb[800*480];//开发板屏幕大小
    lseek(bmp,18,SEEK_SET);//光标偏移18个字节
    read(bmp,&buf_width,4);
    read(bmp,&buf_heigh,4);
    printf("图像宽:%d,图像高: %d\n",buf_width,buf_heigh);
    if(buf_width > 800 || buf_heigh > 480)
    {
        printf("图像尺寸过大,无法显示\n");
        return -1;
    }
    char buf[buf_heigh*buf_width*3];//定义数组大小为图像高度*图像宽度*3,为什么乘以3,因为bmp图片一个像素占3个字节
    printf("111\n");//测试
    /*
    第三步:通过获取到图片宽度,计算系统到底补了多少个字节数。
    !!!读取的图片宽度是像素点数目
    */
    int num,num1;
    num = buf_width*3%4;//这是以四个字节为单位读取,num是多的字节
    if(num == 0)
    {
        num1 = 0;
    }
    else
    {
        num1 = 4 -num;
    }
    int sum ;
    

    
    //第四步:偏移图片开头的54个字节,然后去读取像素点,注意,要一行一行的读,读完每一行的时候,要去跳过系统补齐的字节数
    lseek(bmp,28,SEEK_CUR);
    /*
    这里使用了两种偏移的方法,这一种是在当前光标的基础上往后偏移28个字节.
    为什么是28呢?
    因为图片开头有54个字节,第18个字节往后4个字节是图片宽度,再往后四个字节是图片高度。54-18-4-4=28。
    或者使用56行所使用的光标偏移,SEEK_SET代表回到开头,再直接偏移54个字节即可。
 
    */
    // lseek(bmp,54,SEEK_SET);
    printf("222\n");//测试

    
    /*
    需要完成读取每一行后跳相应补齐的字节.
    假设1行长500个像素,需要补齐的字节是2。
    read(bmp,buf,500);
    lseek(bmp,2,SET_CUR);

    read(bmp,buf+500,500);
    lseek(bmp,2,SET_CUR);
    总结规律为:
    int j;
    for(j=0;j<buf_heigh;j++)
    {
        read(bmp,buf+n*buf_width,buf_width);
        lseek(bmp,num,SET_CUR);
    }
    */
    int j;
    for(j=0;j<buf_heigh;j++)
    {
        read(bmp,buf+j*buf_width*3,buf_width*3);
        lseek(bmp,num1,SEEK_CUR);
    } 
    printf("333\n");//测试
    //第五步:改造像素点
    /*
    简单来说就是根据图片格式的不同所占像素点也不同。
    比如bmp格式三个像素点=开发板一个像素点。
    */
    int x,y;
    int n=0;
    for( y = 0;y<480;y++)
    {
        for(x = 0;x<800 ; x++)
        {
            if( x >= 0 && x < buf_width && y >=0 && y< buf_heigh)
            {
                /*
                argb[800*y+x] = buf[3*n] + buf[3*n+1] + buf[3*n+2];//这种颜色显示偏蓝色且上下颠倒
                */
               argb[800*(479 - y)+x] = buf[3*n] + (buf[3*n + 1] << 8) + (buf[3*n+2] <<16);//这种就是正常显示
               n++;
            }
            else
            {
                argb[800*(479 - y) + x ] = 0x00ffffff;
            }
        }
    }
    printf("444\n");//测试
    //第六步:将改造好的像素点写入到fb0里面去
    ssize_t write_rtn = write(lcd,argb,800*480*4);
    if(write_rtn == -1)
    {
        printf("写入失败\n");
        return -1;
    }
    else
    {
        printf("写入成功\n");
    }
    printf("555\n");//测试
    //最后一步:关闭两个文件
    int close_ret =  close(bmp);
    int close_ret1 = close(lcd);
    if(close_ret1 == -1 || close_ret == -1)
    {
        printf("文件关闭失败\n");
    }
    else
    {
        printf("文件关闭成功\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值