#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;
}
嵌入式开发板6818显示任意大小bmp图片。原码
于 2024-11-22 19:58:39 首次发布