之前学习的时候一个作业,趁机会发表一下做个记录,bmp图片较为简单就可以实现了,关于bmp图片的原理可参考这个链接https://blog.csdn.net/u013066730/article/details/82625158,jpg的话是使用了官方的jpg库,可自行去官方下载http://www.ijg.org/

下面是一些代码

main.c 的内容

/*查找整个系统中的bmp和jpg格式图片,并打印出他们的信息,同时在开发板上显示这张图片*/#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>#define BLACK 0x000000int read_JPEG_file (char * filename,int *lcd);     //读取JPG格式图片信息/*显示.JPG格式的图片*/
void show_jpg(char *photo_path)
{//打开需要映射的硬件设备  int lcd_fd = open("/dev/fb0",O_RDWR);if(lcd_fd < 0){perror("open fail");exit(0); }//映射文件到虚拟内存空间中    int  *lcd_p =  mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);//对JPEG  图片解码并显示read_JPEG_file(photo_path,lcd_p);sleep(1);int i=0;for(i=0;i<800*480;i++){*(lcd_p+i) = BLACK;}//关闭映射和打开的文件munmap(lcd_p,800*480*4);close(lcd_fd);
}/*显示.BMP格式的图片*/
void show_bmp(char *photo_path)
{//打开需要映射的硬件设备int lcd_fd = open("/dev/fb0",O_RDWR);if(!lcd_fd){perror("open");exit(1);}//映射文件到虚拟内存空间中int *lcd_p = mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);int bmp_fd = open(photo_path,O_RDWR);if(!bmp_fd){perror("open");exit(2);}//读取图片的头信息unsigned char head[54]={0};read(bmp_fd,head,54);//处理头数据int chang = *((int *)&head[18]);int kuan = *((int *)&head[22]);int bit = *((int *)&head[28]);printf("chang=%d,kuan=%d,bit=%d\n",chang,kuan,bit);//根据头数据定义像素数据的缓存地址      char color_buf[chang*kuan*(bit/8)];int size = read(bmp_fd,color_buf,sizeof(color_buf));printf("size=%d\n",size);//定义一个数据的缓冲区int buf24[chang*kuan];int i=0;for(i=0;i<chang*kuan;i++){buf24[i]  =  color_buf[i*3+0] |  color_buf[i*3+1]<< 8  | color_buf[i*3+2]  << 16;//B 0-7                 G 8-15                   R:16 - 23}//把图像的数据写入到lcd屏幕设备中int  x=0,y=0;  for(y=0;y<kuan;y++){    for(x=0;x<chang;x++){//超出显示屏范围跳出  if(x >= 800 || y >= 480)break;//图片没有超出显示屏范围else if(chang <= 800 && kuan <= 480 ){*(lcd_p + (800*(480-kuan)/2 + (800-chang)/2) + x + y*800) = buf24[x + (kuan-1-y)*chang];}// 图片长和宽都超出屏幕,显示图片中间800*480部分else if(chang > 800 && kuan > 480){*(lcd_p + x + y*800)  =  buf24[(chang-800)/2 + x + (kuan - (kuan-480)/2 - 1 - y) * chang];}// 图片长超出,宽没有,居中显示else if(chang > 800 && kuan <= 480){*(lcd_p + (800*(480-kuan)/2) + x + y*800) = buf24[(chang-800)/2 + x + (kuan-1-y)*chang];}// 图片宽超出,长没有,居中显示else if(chang <= 800 && kuan > 480){*(lcd_p + (800-chang)/2 + x + y*800) = buf24[x + (kuan - (kuan-480)/2 - 1 - y) * chang];}}}/*图片显示一秒后清屏进入下一张图片*/sleep(1);for(i=0;i<800*480;i++){*(lcd_p+i) = BLACK;}//关闭映射和打开的文件munmap(lcd_p,800*480*4);close(bmp_fd);close(lcd_fd);
}/*实现搜索整个系统中的   .bmp  .jpg 文件 */
int find(char *path)
{DIR *dir=opendir(path);if(dir==NULL){/*根目录下一些文件无法打开,为了不影响观看效果,不打印错误结果*///perror("opedndir");return -1;}while(1){struct dirent *ep = readdir(dir);if(ep==NULL){break;}//跳过隐藏文件if( ep->d_name[0] == '.' ){continue;}//目录if(ep->d_type==DT_DIR){char buf[4096]={0};if(strcmp(path,"/")==0)sprintf(buf,"%s%s",path,ep->d_name);elsesprintf(buf,"%s/%s",path,ep->d_name);//        printf("%s\n",buf);find(buf);}//文件if(ep->d_type==DT_REG){/*  *.bmp 文件   */if(strstr(ep->d_name,".bmp") != NULL ){if(strcmp(strstr(ep->d_name,".bmp"),".bmp") == 0){if(strcmp(path,"/")==0)printf("%s%s",path,ep->d_name);elseprintf("%s/%s\n",path,ep->d_name);char buf1[4096]={0};if(strcmp(path,"/")==0)sprintf(buf1,"%s%s",path,ep->d_name);elsesprintf(buf1,"%s/%s",path,ep->d_name);show_bmp(buf1);}}/*  *.jpg  文件  */if(strstr(ep->d_name,".jpg") != NULL){if(strcmp(strstr(ep->d_name,".jpg"),".jpg") == 0){if(strcmp(path,"/")==0)printf("%s%s",path,ep->d_name);elseprintf("%s/%s\n",path,ep->d_name);char buf2[4096]={0};if(strcmp(path,"/")==0)sprintf(buf2,"%s%s",path,ep->d_name);elsesprintf(buf2,"%s/%s",path,ep->d_name);show_jpg(buf2);}}}}closedir(dir);
}int main(int argc,char *argv[])
{find("/");printf("\nOver!!!");printf("\n\n");
}

jpg.c的内容


#include <stdio.h>
#include "jpeglib.h"
#include <setjmp.h>extern JSAMPLE * image_buffer; /* Points to large array of R,G,B-order data */
extern int image_height;    /* Number of rows in image */
extern int image_width;     /* Number of columns in image */struct my_error_mgr {struct jpeg_error_mgr pub; /* "public" fields */jmp_buf setjmp_buffer;   /* for return to caller */
};typedef struct my_error_mgr * my_error_ptr;/** Here's the routine that will replace the standard error_exit method:*/METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */my_error_ptr myerr = (my_error_ptr) cinfo->err;/* Always display the message. *//* We could postpone this until after returning, if we chose. */(*cinfo->err->output_message) (cinfo);/* Return control to the setjmp point */longjmp(myerr->setjmp_buffer, 1);
}//功能:读取jpeg 文件中的数据转换成  r g b 值
int read_JPEG_file (char * filename,int *lcd)
{//定义一个 jpeg  的解码对象 struct jpeg_decompress_struct cinfo;//定义一个jpeg  的出错对象 struct my_error_mgr jerr;/* More stuff */FILE * infile;       /*源文件*/JSAMPARRAY buffer;       /*输出行缓存*/int row_stride;        /*输出行缓存的宽度*///打开源文件if ((infile = fopen(filename, "rb")) == NULL) {fprintf(stderr, "can't open %s\n", filename);return 0;}/* Step 1: 初始化JPEG 解码对象*//*初始化出错对象 */cinfo.err = jpeg_std_error(&jerr.pub);jerr.pub.error_exit = my_error_exit;/* Establish the setjmp return context for my_error_exit to use. */if (setjmp(jerr.setjmp_buffer)) {jpeg_destroy_decompress(&cinfo);fclose(infile);return 0;}/*初始化解码对象*/jpeg_create_decompress(&cinfo);/* Step 2: 关联源文件与解码对象*/jpeg_stdio_src(&cinfo, infile);/* Step 3: 读取jpeg图像的头数据*/(void) jpeg_read_header(&cinfo, TRUE);/* Step 5: 开始解码*/(void) jpeg_start_decompress(&cinfo);/* 一行所占用的字节数 */row_stride = cinfo.output_width * cinfo.output_components;/*为输出行缓存分配堆空间*/buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);//cinfo.output_width * cinfo.output_componentsint buf24[cinfo.output_width*cinfo.output_height];//重点!!!!! 循环对每一行数据进行解码!! while (cinfo.output_scanline < cinfo.output_height) {//printf("%d\n",cinfo.output_scanline);//读取一行数据进行解码 并 写入到 buffer 中(void) jpeg_read_scanlines(&cinfo, buffer, 1);char *p = buffer[0];  //指向数据的R G B 数据的缓存首地址  int i=0; for(i=0;i<cinfo.output_width;i++)  //把一行的 R G B 值全部都取出来  {    char  r = *p++; char  g = *p++;char  b = *p++;     buf24[i + (cinfo.output_scanline-1) * cinfo.output_width] = r << 16 | g << 8 | b;   // 处理 jpeg 中的RGB 数据 }}    //把图像的数据写入到lcd屏幕设备中int x = 0, y = 0;for(y=0;y<cinfo.output_height;y++){for(x=0;x<cinfo.output_width;x++){//超出显示屏范围跳出  if(x >= 800 || y >= 480)break;//图片没有超出显示屏范围else if(cinfo.output_width <= 800 && cinfo.output_height <= 480 ){*(lcd + (800*(480-cinfo.output_height)/2 + (800-cinfo.output_width)/2) + x + y*800) = buf24[x + y*cinfo.output_width];}// 图片长和宽都超出屏幕,显示图片中间800*480部分else if(cinfo.output_width > 800 && cinfo.output_height > 480){*(lcd + x + y*800)  =  buf24[(cinfo.output_width-800)/2 + x + ((cinfo.output_height-480)/2 + y) * cinfo.output_width];}// 图片长超出,宽没有,居中显示else if(cinfo.output_width > 800 && cinfo.output_height <= 480){*(lcd + (800*(480-cinfo.output_height)/2) + x + y*800) = buf24[(cinfo.output_width-800)/2 + x + y*cinfo.output_width];}// 图片宽超出,长没有,居中显示else if(cinfo.output_width <= 800 && cinfo.output_height > 480){*(lcd + (800-cinfo.output_width)/2 + x + y*800) = buf24[x + ((cinfo.output_height-480)/2 +y) * cinfo.output_width];}}}//*(lcd + (cinfo.output_scanline - 1)*800 + i)  = color;   //把转换后的颜色数据赋值给   lcd 屏幕 //cinfo.output_scanline*800 第几行  //把解码后的数据输出 LCD 屏幕中// put_scanline_someplace(buffer[0], row_stride);/* Step 7: Finish decompression */(void) jpeg_finish_decompress(&cinfo);jpeg_destroy_decompress(&cinfo);fclose(infile);return 1;
}

测试用的机器是arm架构、linux系统的粤嵌公司的6818开发板,最终实现效果就是在屏幕上轮流播放内存里面的所有bmp和jpg格式的图片。

在arm开发板上实现播放内存里所有的jpg和bmp格式图片相关推荐

  1. 将linux内核烧进arm板,ARM开发板上uClinux内核移植

    <ARM开发板上uClinux内核移植>由会员分享,可在线阅读,更多相关<ARM开发板上uClinux内核移植(19页珍藏版)>请在人人文库网上搜索. 1.纷傲掌秀悸篷益哑檀扬 ...

  2. 【linux】ARM开发板上设置RTC时间,断电重启后,设置失效的原因分析

    问题描述 linux中使用date设置时间后用hwclock -w同步到RTC,断电重启后,有时会失效 原因分析 保存时间戳 1.使用命令关机(halt)会调用rc0.d中的脚本: 2.使用命令重启( ...

  3. 如何在ARM开发板上从源码编译安装OpenCV和OpenCV contrib

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 本文主要介绍如何在ARM开发板上从源码编译安装OpenCV和OpenCV contrib. OpenC ...

  4. ARM开发板上iconv_open(utf-8, gb2312) 调用失败的解决方法(转)

    ARM开发板上iconv_open("utf-8", "gb2312") 调用失败的解决方法 应用程序代码如下: static int code_convert ...

  5. 摄像头在liunx上的QT显示和OK6410 ARM开发板上的使用

    摄像头在liunx上的QT显示和OK6410 ARM开发板上的使用 发布者:旺旺雪饼   时间:2013-01-05 16:56:09 环境: Ubuntu10.04 arm linux OS: 3. ...

  6. python交叉编译_交叉编译Python3.6.2,使用海思arm-hisiv200-linux-gcc,移植到arm开发板上...

    最近在学习Python,感觉使用Python可以快速的写出程序,比之前使用的C语言快多了,能省出很多时间.多学一点知识有更多的选择.本职工作是嵌入式开发,学习了Python后想移植到开发板上,尝试嵌入 ...

  7. linux usb视频开发板,ARM开发板上USB 摄像头图像采集实现

    开发板上的arm是AT91RM9200,摄像头选用的是网眼的pc350,主控芯片是ov511+.系统内核是2.4,宿主机是fedora core 6,交叉编译器是2.95.3.就是这些家底了,:-). ...

  8. 在ARM开发板上实现LCD+USB键盘

    一.LCD驱动 这个地方先留着 二.USB键盘驱动 在linux内核里边提供了usbkbd.c可以直接借助这个模块,编译生成驱动模块加载进内核,其实对于驱动程序,这里还不是重点,最后想要实现的是直接在 ...

  9. arm开发板上4G网络转为以太网口供其他设备使用

    一个设备和ARM开发板的以太网口连接使用4G模块实现上网 最后做完发现只要思路对,没什么特别难的东西要做,开始我一直以为是路由表.arp的问题,其实都不是,只是IP地址转换的问题,其他都不需要动.之前 ...

最新文章

  1. 若变量均已正确定义并赋值,以下合法的c语言赋值语句是,若变量均已正确定义并赋值,以下合法的C语言赋值语句是()...
  2. 香港大学提出OneNet:一阶段端到端目标检测网络,无需NMS!无需二分匹配!
  3. harris角点检测_角点检测(2) - harris算子 - 理论与Python代码
  4. 《漫画算法2》源码整理-6 两数之和 三数之和
  5. » Markdown/reST 编辑器 ReText 3.0 发布 Wow! Ubuntu
  6. Linux/Centos Tomcat 配置日志切分以及脚本自动清理
  7. RHCE 学习笔记(24) - LVM 逻辑卷
  8. 课程 预编译框架,开发高性能应用 - 微软技术暨生态大会 2018
  9. CentOS7显卡驱动问题
  10. pt-heartbeat 监测RDS延迟
  11. 苹果宣布取消AirPower 因技术难题无法攻克
  12. JavaScript——事件,DOM,Browser Object Model 浏览器对象模型,电灯开关,HTML DOM,表单动态添加
  13. php源码比赛,TSRC挑战赛: PHP防御绕过挑战实录
  14. CF 1538 G. Gift Set (贪心+思维)
  15. 大一计算机题库百度云,《大学计算机基础》试题题库及答案.doc
  16. 注意力CBMA到底在网络中做了什么事
  17. 如何写好一篇论文的摘要?
  18. PXIEBPMCx4载板转接卡
  19. Halcon每月授权license如何更新
  20. 基于AT89C51单片机的温度计设计

热门文章

  1. centos 安装五笔输入法
  2. 电脑怎么安装免费的office
  3. 计算机专业社会实践事例,关于计算机专业的社会实践模板
  4. Vista下输入法的使用
  5. “遗憾中国”7大IT名人
  6. 使用python脚本登陆ef英语学习中心
  7. CiteSpace学习笔记(二)——数据的获取(科技文献检索)
  8. xp系统itunes无法验证服务器的身份,itunes无法验证服务器身份
  9. 碧桂园博智林机器人总部大楼_碧桂园的800亿机器人梦,烧了两年,陷入窘境
  10. 如何阻止事件冒泡和默认事件 1