推荐阅读:C语言实现2048小游戏—粤嵌GE6818嵌入式系统实训
C语言实现电子音乐相册—粤嵌GE6818嵌入式系统实训

要求

练习: 完成一张图片在板子上的显示
要求: 任意路径的图片
任意大小的图片
在板子上的任意位置显示

思路

 void show_bmp (char * pathname ,  int x,int y){第一步:打开图片 ,读取宽度 高度 色深 第二步: 确定总字节数  然后malloc对应大小的内来保存这些颜色。unsigned char * p = malloc(total_bytes);//第三步: 打开帧缓冲设备  映射    init(); end();第四步: 把颜色的值写进去 要一个字节一个字节地写入 为什么呢?   因为32位和24位地A是不一样的。unsigned char a,r,g,b ;我们把前面保存的像素数组的对应内容 一个一个字节地给我的argb 。24位的像素数组只有RGB    a直接给0 32位的像素数组有a  需要给一个字节给a 每写完四个字节  写完一个argb 。 这四个字节是不是就是组成一个color ? 这个时候是不是就该调用我们draw_point函数。注意: 每行跳过癞子。第五步: 关闭图片 //关闭帧缓冲 解除映射}

代码

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
#include <math.h>
#include <stdlib.h>
int * p = NULL ;void draw_point(int x,int y,int color)
{if(x>=0 && x<800 && y>=0 && y<480 ){*(p+800*y+x) = color ;}
}
/*
函数功能:在屏幕的任意一个位置  显示任意一张  任意大小的bmp图片
函数参数: @pathname : 要显示的图片 的路径名 @x : 在屏幕X轴值为x的地方开始显示@y :  在屏幕Y轴值为y的地方开始显示
*/
void show_bmp (char * pathname ,int x ,int y)
{int fd = open(pathname,O_RDONLY);if(fd == -1){perror("open error\n");return ;}int fd1 = open("/dev/fb0",O_RDWR);if(fd1 == -1){perror("open error\n");return ;}printf("open success\n");p = mmap(NULL,800*480*4,PROT_READ | PROT_WRITE,MAP_SHARED ,fd1,0);if(p == NULL ){perror("mmap error\n");return ;}int width,height;short depth;unsigned char buf[4] ;//读取宽度lseek(fd,0x12,SEEK_SET);read(fd,buf,4);width = buf[3]<<24 | buf[2]<< 16 | buf[1] << 8 | buf[0];//读取高度read(fd,buf,4);height  = buf[3]<<24 | buf[2]<< 16 | buf[1] << 8 | buf[0];//读取色深lseek(fd,0x1c,SEEK_SET);read(fd,buf,2);depth = buf[1] << 8  | buf[0];//打印信息printf("width = %d  height = %d  depth = %d \n",width,height,depth);//像素数组 int line_valid_bytes = abs(width) * depth / 8 ; //一行本有的有效字节int laizi=0;//填充字节if( (line_valid_bytes % 4) !=0   ){laizi =  4 - line_valid_bytes%4;}int line_bytes = line_valid_bytes  +  laizi ;//一行所有的字节数int total_bytes = line_bytes * abs(height) ; //整个像素数组的大小unsigned char * p1  = malloc(total_bytes);lseek(fd,54,SEEK_SET);read(fd,p1,total_bytes);//调用draw_point 函数 。unsigned char a ,r ,g, b ;int i = 0;//用来做指针运动的int x0=0,y0=0; //用来循环计数int color ;for(y0=0;y0<abs(height);y0++)//画满每一列{for(x0=0;x0<abs(width);x0++)//画满每一行{//现在开始一个字节一个字节写入颜色// i++  先用后加     // ++i  先加后用b = p1[i++];g = p1[i++];r = p1[i++];if(depth == 32){a=p1[i++];}if(depth == 24){a = 0;}color = a << 24 | r << 16 | g << 8 | b ;draw_point(width>0?x+x0:abs(width)+x-1-x0,height>0? y+height-1-y0 : y+y0,color);}i = i +laizi ;//每一行后面的癞子数 跳过去。}free(p1);close(fd1);munmap(p,800*480*4);close(fd);}
int main()
{show_bmp("1.bmp",-100 ,-100);//show_bmp("3.bmp",0,0);return 0;
}

具体步骤

1、读取文件设置缓冲区

int fd = open(pathname,O_RDONLY);if(fd == -1){perror("open error\n");return ;}int fd1 = open("/dev/fb0",O_RDWR);if(fd1 == -1){perror("open error\n");return ;}printf("open success\n");

2、测量待显示图片的宽度、高度、色深

p = mmap(NULL,800*480*4,PROT_READ | PROT_WRITE,MAP_SHARED ,fd1,0);if(p == NULL ){perror("mmap error\n");return ;}int width,height;short depth;unsigned char buf[4] ;//读取宽度lseek(fd,0x12,SEEK_SET);read(fd,buf,4);width = buf[3]<<24 | buf[2]<< 16 | buf[1] << 8 | buf[0];//读取高度read(fd,buf,4);height  = buf[3]<<24 | buf[2]<< 16 | buf[1] << 8 | buf[0];//读取色深lseek(fd,0x1c,SEEK_SET);read(fd,buf,2);depth = buf[1] << 8  | buf[0];//打印信息printf("width = %d  height = %d  depth = %d \n",width,height,depth);
  • BMP图片的显示 :
    bmp:bit map picture 位图
    bmp文件格式的图片, 没有经过任何压缩技术生成的图片。
    无压缩:保存了图片的每一个像素点的rgb颜色分量的值。
    我们按照bmp图片文件的固定的内容格式将他的数据读出来,进行一些简单的操作。我们就可以完成这个图片的显示。
    BMP图片文件格式
    见图:
    头两个字节 BM 我们是自己用BMP图片 所以就不用判定。
 宽度: 一行有多少个像素点:偏移量:0x12 大小: 4个字节可正可负 正负只表示一行像素点的存储方式为正说明行像素点是从左到右排列为负说明行像素点是从右往左排列高度: 一列有多少个像素点偏移量:0X16大小 : 4个字节可正可负 正负只表示一列像素点的存储方式为正说明行像素点是从下到上排列为负说明行像素点是从上往下排列色深: 每个像素所占的位数 bit  怎么求每个像素的大小?字节色深/824 32  偏移量:0x1c大小: 2个字节

小端模式和大端模式
小端模式: 存储器(内存)的低地址 存放 寄存器(数据)的低地址字节
大端模式: 存储器(内存)的低地址 存放 寄存器(数据)的高地址字节
两者的区别就是 高字节位、低字节位存放次序不同;小端先存低,大端先存高,大端模式用于比较高端的场景,处理速度快。

 获取图片的宽度 高度 色深信息。思路: int width,height;short depth;unsigned char buf[4];第一步: 打开图片  open("./1.bmp")第二步: lseek 偏移对应偏移量大小read   读取对应数据大小的内容。。。。。第三步: 关闭图片buf[4]buf[0]  buf[1]  buf[2]  buf[3]  我们真正想要的正确的数据是多少buf[3]  buf[2]  buf[1]  buf[0] buf[0]  buf[1]  buf[2]  buf[3]  ---> buf[3]  buf[2]  buf[1]  buf[0] buf[3] << 24        buf[3]    _______    ________    _________  buf[2] << 16       _________   buf[2]  __________  ___________buf[1] << 8       __________  _______   buf[1]   ____________buf[0]             _________  _________  ________     buf[0]width = buf[3] << 24 | buf[2] << 16 | buf[1] << 8  | buf[0]

将图像字节写入一个数组

//像素数组 int line_valid_bytes = abs(width) * depth / 8 ; //一行本有的有效字节int laizi=0;//填充字节if( (line_valid_bytes % 4) !=0   ){laizi =  4 - line_valid_bytes%4;}int line_bytes = line_valid_bytes  +  laizi ;//一行所有的字节数int total_bytes = line_bytes * abs(height) ; //整个像素数组的大小unsigned char * p1  = malloc(total_bytes);

像素数组: 保存了图片像素点的所有argb颜色分量的值

 偏移量: 54大小:  ???大小需要根据宽度和高度和色深来求 。格式规定图片每行的字节数为4字节的倍数大小: 图片的宽度的绝对值   *  图片的高度的绝对值  *  色深/ 8if(depth == 32){(图片的宽度的绝对值  *  32/ 8) % 4 一定为0 ;}if(depth == 24 ){(图片的宽度的绝对值  *  24 / 8)  % 4  不一定为 0 ;}是不是我们24位的图片就需要填充若干个字节 来满足每行大小为4字节倍数要求这些填充的字节数 我们叫癞子。那我们怎么求出每行的填充的字节数呢?癞子?int laizi;if (    ( 宽度*色深/8 ) %4  !=0    ){laizi = 4 -  宽度*色深/8 ) %4 ;}我真正意义上一行的字节数 是多少?   line_bytes = ( 宽度*色深/8 ) %4   +  laizi ;总共的字节数呢?     total_bytes = line_bytes * height unsigned char * p = malloc(total_bytes);

将图像字节写入屏幕

void draw_point(int x,int y,int color)
{if(x>=0 && x<800 && y>=0 && y<480 ){*(p+800*y+x) = color ;}
}
lseek(fd,54,SEEK_SET);read(fd,p1,total_bytes);//调用draw_point 函数 。unsigned char a ,r ,g, b ;int i = 0;//用来做指针运动的int x0=0,y0=0; //用来循环计数int color ;for(y0=0;y0<abs(height);y0++)//画满每一列{for(x0=0;x0<abs(width);x0++)//画满每一行{//现在开始一个字节一个字节写入颜色// i++  先用后加     // ++i  先加后用b = p1[i++];g = p1[i++];r = p1[i++];if(depth == 32){a=p1[i++];}if(depth == 24){a = 0;}color = a << 24 | r << 16 | g << 8 | b ;draw_point(width>0?x+x0:abs(width)+x-1-x0,height>0? y+height-1-y0 : y+y0,color);}i = i +laizi ;//每一行后面的癞子数 跳过去。}

注意事项

  • bmp图片需要传在GEC818上
  • 如果要显示两张图片改变两张图片的起始位置即可
  • width>0?x+x0:abs(width)+x-1-x0
    当width>0,也就是从左到右时,横坐标位置为x+x0
    当width<0,也就是从右到左时,横坐标位置为abs(width)+x-1-x0`
模块化思想: 。。。只有一个唯一的main函数‘一个或者多个功能函数 main.clcd.c   lcd.hbmp.c   bmp.hled.c   led.hbeef.c   beef.h......h怎么写? 例:led.h#ifndef  __LED_H__#define  __LED_H__// 变量的定义 // 函数的声明//。。。#endif功能函数: 封装一个函数 /*功能函数:对一个坐标点为(x,y)的像素点上色。参数: @x : 像素点的X轴坐标值@y :像素点的Y轴坐标值@color : 要画的颜色*/void draw_point (  int x, int y, int color ){if(x>=0 && x<800 && y>=0 && y<480)*(p + 800*y +x ) = 0x00ff0000 ;//p定义成全局变量}BMP图片的显示 : bmp:bit map picture 位图bmp文件格式的图片, 没有经过任何压缩技术生成的图片。无压缩:保存了图片的每一个像素点的rgb颜色分量的值。我们按照bmp图片文件的固定的内容格式将他的数据读出来,进行一些简单的操作。我们就可以完成这个图片的显示。BMP图片文件格式 见图:头两个字节  BM 我们是自己用BMP图片 所以就不用判定。宽度: 一行有多少个像素点: 偏移量:0x12 大小: 4个字节 可正可负 正负只表示一行像素点的存储方式为正说明行像素点是从左到右排列为负说明行像素点是从右往左排列高度: 一列有多少个像素点偏移量:0X16大小 : 4个字节可正可负 正负只表示一列像素点的存储方式为正说明行像素点是从下到上排列为负说明行像素点是从上往下排列色深: 每个像素所占的位数 bit  怎么求每个像素的大小?字节色深/824 32  偏移量:0x1c大小: 2个字节小端模式和大端模式 小端模式: 存储器(内存)的低地址  存放 寄存器(数据)的低地址字节大端模式: 存储器(内存)的低地址  存放 寄存器(数据)的高地址字节练习: 获取图片的宽度 高度 色深信息。思路: int width,height;short depth;unsigned char buf[4];第一步: 打开图片  open("./1.bmp")第二步: lseek 偏移对应偏移量大小read   读取对应数据大小的内容。。。。。第三步: 关闭图片buf[4] buf[0]  buf[1]  buf[2]  buf[3]  我们真正想要的正确的数据是多少buf[3]  buf[2]  buf[1]  buf[0] buf[0]  buf[1]  buf[2]  buf[3]  ---> buf[3]  buf[2]  buf[1]  buf[0] buf[3] << 24        buf[3]    _______    ________    _________  buf[2] << 16       _________   buf[2]  __________  ___________buf[1] << 8       __________  _______   buf[1]   ____________buf[0]             _________  _________  ________     buf[0]width = buf[3] << 24 | buf[2] << 16 | buf[1] << 8  | buf[0] 同样的方法求高度 色深...见code  : 像素数组: 保存了图片像素点的所有argb颜色分量的值偏移量: 54大小:  ???大小需要根据宽度和高度和色深来求 。大小: 图片的宽度的绝对值   *  图片的高度的绝对值  *  色深/ 8if(depth == 32){(图片的宽度的绝对值  *  32/ 8) % 4 一定为0 ;}if(depth == 24 ){(图片的宽度的绝对值  *  24 / 8)  % 4  不一定为 0 ;}是不是我们24位的图片就需要填充若干个字节 来满足每行大小为4字节倍数要求这些填充的字节数 我们叫癞子。那我们怎么求出每行的填充的字节数呢?癞子?int laizi;if (    ( 宽度*色深/8 ) %4  !=0    ){laizi = 4 -  宽度*色深/8 ) %4 ;}我真正意义上一行的字节数 是多少?   line_bytes = ( 宽度*色深/8 ) %4   +  laizi ;总共的字节数呢?     total_bytes = line_bytes * height unsigned char * p = malloc(total_bytes);练习: 完成一张图片在板子上的显示要求: 任意路径的图片 任意大小的图片在板子上的任意位置显示 void show_bmp (char * pathname ,  int x,int y){第一步:打开图片 ,读取宽度 高度 色深 第二步: 确定总字节数  然后malloc对应大小的内来保存这些颜色。unsigned char * p = malloc(total_bytes);//第三步: 打开帧缓冲设备  映射    init(); end();第四步: 把颜色的值写进去 要一个字节一个字节地写入 为什么呢?   因为32位和24位地A是不一样的。unsigned char a,r,g,b ;我们把前面保存的像素数组的对应内容 一个一个字节地给我的argb 。24位的像素数组只有RGB    a直接给0 32位的像素数组有a  需要给一个字节给a 每写完四个字节  写完一个argb 。 这四个字节是不是就是组成一个color ? 这个时候是不是就该调用我们draw_point函数。注意: 每行跳过癞子。第五步: 关闭图片 //关闭帧缓冲 解除映射}

效果图

粤嵌GEC6818实现图片显示相关推荐

  1. 粤嵌gec6818开发板轮流显示颜色

    粤嵌gec6818开发板轮流显示颜色 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> ...

  2. 基于粤嵌gec6818开发板嵌入式开发电子相册,音乐播放,视频播放,2048游戏

    一.功能与要求 实现功能:本系统需要使用粤嵌的GEC-6818开发板设计一款娱乐影音系统,其中包括图片显示(相册).音乐播放.视频播放,游戏四个部分,在每个部分内部,具有操控各个部分的功能触摸按键.本 ...

  3. C语言实现电子音乐相册---粤嵌GEC6818嵌入式系统实训

    C语言实现电子音乐相册---粤嵌GEC6818嵌入式系统实训 功能演示: 版本介绍 滑动式 点击放大式 完整版 至尊版 获取方式 功能演示: 演示视频: 滑动式 点击放大式 版本介绍 分为滑动式.点击 ...

  4. 模块化思想——粤嵌GEC6818读取图片宽度、高度、色深

    推荐阅读:C语言实现2048小游戏-粤嵌GEC6818嵌入式系统实训 C语言实现电子音乐相册-粤嵌GEC6818嵌入式系统实训 模块化思想 交叉编译两个c文件的方法: 模块化思想: ... 只有一个唯 ...

  5. 粤嵌GEC6818开发板-入门感慨篇

    第一次接触嵌入式开发,小脑袋是一篇空白,度娘各种资料,零零碎碎,似懂非懂,确实有点懵逼. 1.前期准备 粤嵌GEC6818开发板一套,USB转串口线一根(简称A线),网线一根(简称N线)(可选).用A ...

  6. 粤嵌GEC6818,基于LVGL和mplayer的音视频播放器

    #include <myplay.h> pthread_mutex_t mutex_lv;//lvgl线程锁 static char local_music_path[]="/t ...

  7. 粤嵌gec6818项目设计_西安市幸福林带景观及亮化设计国际竞赛终期评审会顺利举行...

    4月1日,由西安市幸福路地区综合改造管理委员会主办,西安市幸福路地区开发建设有限公司.中建西安幸福林带建设投资有限公司.中国风景园林网承办的西安市幸福林带景观及亮化设计国际竞赛终期评审顺利举行.评审现 ...

  8. 粤嵌GEC-6818

    影音娱乐系统主界面 主程序 main.c #include "head.h" int* p_lcd = NULL; // 屏幕映射内存的起始地址 //显示开机动画 void sho ...

  9. 粤嵌GEC6818板子TCP网络编程发送命令控制音视频

    TCP网络编程 (1)gec6818网络编程前期准备工作 (1).开发板和Ubuntu系统都处于教室局域网内 1.开发板和电脑(Ubuntu)都需要连接上教室的网线 2.开发板设置ip地址 在开发板终 ...

最新文章

  1. 解密初、中、高级程序员的进化之路
  2. oauth2.0里回调地址返回code中如何让code不显示在URL里?
  3. Effective Java之用EnumSet代替位域(三十二)
  4. 8个球放入3个盒子方式_8种土豆做法,好吃到根本停不下来!
  5. Reset Password 重置密码 (CentOS 5,6,7 ; Juniper Networks: SRX100 )
  6. c语言学习-使用指针求一个字符串的长度
  7. JavaScript 编码指南
  8. “数据治理”:重构和愿景
  9. 计算机组成原理:最详细笔记
  10. 2023西安电子科技大学计算机考研信息汇总
  11. Rundll32.exe 转自5iuu.com
  12. pscp实现windows和linux之间互传文件
  13. 介词短语不能做宾语,但有时有的借此有句意省略就出现了介词再加上介词短语了
  14. 软件工程 个人学习笔记(第二章)
  15. python网格交易法详解_详解低风险投资策略—详解网格交易法
  16. 微信“公众平台测试账号”接口调试指南
  17. Python实现秒杀某宝商品抢购(附超详细代码)
  18. 【PV操作】南航重点:过独木桥
  19. virtualenv: error: argument dest: the destination . is not write-able at /User/de/ .virtualenvs解决方法
  20. arduino彩灯计时器电路_Arduino UNO 制作LED节日彩灯

热门文章

  1. 论文阅读:FACIAL: Synthesizing Dynamic Talking Face with Implicit Attribute Learning
  2. 安卓全屏java模拟器如何安装_使用Android 模拟器运行自定义Rom
  3. 关于不定期弹出http://u.9kuku.com/的问题
  4. 服务器插无线usb网卡驱动,cubieboard安装USB无线网卡驱动及设置
  5. 光遇显示服务器已满怎么办,光遇服务器已满怎么办 光遇服务器已满您正在登陆队列中解决方法...
  6. java 实现汉字转换拼音_Java实现汉字转换为拼音
  7. 三分钟学会快速排序(图示讲解,附代码,通俗易懂)
  8. python warning
  9. linux下文件与Windows下文件格式的区别与转换
  10. mysql查询中位数