通过写framebuffer显示BMP图片
- 格式:doc
- 大小:27.50 KB
- 文档页数:5
VC环境下读取显示.bmp图像方法总结显示bmp图像的方法,列出四种显示方法。
1 通过SetPixel()函数画出每个像素点来显示图像。
2 通过读取位图资源中bmp资源显示图像。
3 通过读取本地文件,利用位图结构信息,定义HGLOBAL,再采用固定的显示方式显示位图。
4 通过读取本地文件,利用位图结构信息,定义buffer,再采用SetDIBitsT oDevice()函数。
下面分别对这四种方法进行详细描述:首先新建VC工程ShowBmpImage->MFC->单文档模式。
将显示的操作都是放在CShowBmpImageView下进行的,并且没有定义成员变量。
1 第一种方法通过SetPixelShow()函数循环画出每个像素点,从而显示图像。
操作如下:增加成员函数SetPixelShow(),编辑代码如下:int x,y; //定义像素位置CClientDC dc(this); //获取dc,也可以用CDC *pDCfor(x=0;x<200;x++)for(y=0;y<200;y++)dc.SetPixel(x,y,RGB(x,y,255)); //画一个像素点,RGB是颜色调用函数后,显示的是一幅彩色图像,可以根据需要改变RGB的值来显示一幅完整的图像。
2 第二种方法通过读取位图资源中的位图显示图像,选择菜单栏->插入->资源,弹出对话框,选择导入按钮,将文件类型改成所有文件,选择想要显示bmp位图,导入。
这样工程的资源位图中,导入的位图默认的ID 是IDB_BITMAP1。
而显示这种位图有一个固定的显示模式,非常方便。
方法如下:a 定义一个CBitmap对象,使其加载位图资源。
b 定义一个CDC对象,用于装载位图;使其创建兼容DC,相当于初始化;与CBitmap对象关联起来,相当于获取位图。
c 定义BITMAP对象,使其与CBitmap对象绑定,可以获取宽度和高度。
从入门到精通嵌入式Linux系统中的图片解码和显示嵌入式Linux系统是一种在资源受限的嵌入式设备上运行的操作系统,它在嵌入式行业得到广泛应用。
图片解码和显示是嵌入式Linux系统中常见的功能之一。
本文将介绍从入门到精通嵌入式Linux系统中的图片解码和显示的方法和技巧。
一、使用嵌入式Linux系统的图形库嵌入式Linux系统提供了多个图形库,其中最常用的图形库包括Frame Buffer(帧缓冲)和DirectFB(直接帧缓冲)。
这两个图形库都可以用于图片解码和显示功能。
1. Frame Buffer(帧缓冲)Frame Buffer是Unix系统中最早引入的一个图形接口,它提供了一种将图像数据直接存储在显存中的方法,从而可以直接在屏幕上显示图像。
使用Frame Buffer进行图片解码和显示的方法如下:(1)初始化Frame Buffer设备首先,需要在嵌入式Linux系统中初始化Frame Buffer设备。
可以通过修改系统启动文件来加载Frame Buffer驱动程序,并配置相关参数。
(2)解码图片数据接下来,需要解码图片数据。
可以使用开源的图像库,如libjpeg和libpng,来解码常见的JPEG和PNG格式的图片。
(3)将解码后的图像数据写入Frame Buffer最后,将解码后的图像数据写入Frame Buffer中的显存,从而在屏幕上显示图像。
2. DirectFB(直接帧缓冲)DirectFB是一个轻量级、高性能的图形库,它直接操作帧缓冲设备,提供了更快速和灵活的图像显示功能。
使用DirectFB进行图片解码和显示的方法如下:(1)初始化DirectFB环境首先,需要在嵌入式Linux系统中初始化DirectFB环境。
可以通过加载DirectFB驱动程序,并进行相关配置来实现。
(2)解码图片数据同样,使用开源的图像库,如libjpeg和libpng,来解码JPEG和PNG格式的图片。
framebuffer简介帧缓冲(framebuffer)是Linux为显示设备提供的一个接口,把显存抽象后的一种设备,他允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。
framebuffer是LCD对应的一中HAL(硬件抽象层),提供抽象的,统一的接口操作,用户不必关心硬件层是怎么实施的。
这些都是由Framebuffer设备驱动来完成的。
帧缓冲设备对应的设备文件为/dev/fb*,如果系统有多个显示卡,Linux下还可支持多个帧缓冲设备,最多可达32个,分别为/dev/fb0到/dev/fb31,而/dev/fb则为当前缺省的帧缓冲设备,通常指向/dev/fb0,在嵌入式系统中支持一个显示设备就够了。
帧缓冲设备为标准字符设备,主设备号为29,次设备号则从0到31。
分别对应/dev/fb0-/dev/fb31。
通过/dev/fb,应用程序的操作主要有这几种:1.读/写(read/write)/dev/fb:相当于读/写屏幕缓冲区。
2.映射(map)操作:由于Linux工作在保护模式,每个应用程序都有自己的虚拟地址空间,在应用程序中是不能直接访问物理缓冲区地址的。
而帧缓冲设备可以通过mmap()映射操作将屏幕缓冲区的物理地址映射到用户空间的一段虚拟地址上,然后用户就可以通过读写这段虚拟地址访问屏幕缓冲区,在屏幕上绘图了。
3.I/O控制:对于帧缓冲设备,对设备文件的ioctl操作可读取/设置显示设备及屏幕的参数,如分辨率,屏幕大小等相关参数。
ioctl的操作是由底层的驱动程序来完成的。
在应用程序中,操作/dev/fb的一般步骤如下:1.打开/dev/fb设备文件。
2.用ioctl操作取得当前显示屏幕的参数,根据屏幕参数可计算屏幕缓冲区的大小。
3.将屏幕缓冲区映射到用户空间。
4.映射后即可直接读写屏幕缓冲区,进行绘图和图片显示。
framebuffer相关数据结构介绍1. fb_info结构体:帧缓冲设备中最重要的数据结构体,包括了帧缓冲设备属性和操作的完整性属性。
嵌入式Linux系统的图片解码和显示方法详解嵌入式Linux系统在如今的物联网应用中扮演着重要的角色。
其中,图片解码和显示是嵌入式系统中常见的需求,它们对于展示图形化界面、实现图像处理等方面都具有重要意义。
本文将详细讨论嵌入式Linux系统中的图片解码和显示方法。
一、图片解码方法在嵌入式Linux系统中,常见的图片格式有JPEG、PNG、BMP等。
针对不同的图片格式,可以采用不同的解码方法。
1. JPEG解码JPEG是一种广泛应用于图像压缩和存储的格式。
在嵌入式Linux系统中,常用的JPEG解码库有libjpeg和libturbojpeg等。
libjpeg是一个开源的JPEG解码库,广泛应用于多个平台。
该解码库提供了一系列的API接口,可以方便地在嵌入式Linux系统中进行JPEG解码操作。
通过使用libjpeg库,可以将JPEG图片解码为RGB格式,从而在系统中进行后续的图像处理或显示。
libturbojpeg是libjpeg的增强版,它在性能上有一定的优化,特别适用于有限的资源嵌入式系统。
libturbojpeg同样提供了丰富的API接口,可以实现对JPEG图片的高效解码。
2. PNG解码PNG是一种无损的位图格式,广泛应用于图像存储和传输。
在嵌入式Linux系统中,可以使用libpng库进行PNG图片的解码。
libpng是一个开源的PNG解码库,它提供了灵活的API接口,可以实现对PNG图片的解码和处理。
通过libpng库,可以将PNG 图片解码为RGBA格式,方便在系统中进行进一步的图像处理或显示。
3. BMP解码BMP是一种非压缩的位图格式,可以直接在屏幕上显示。
在嵌入式Linux系统中,可以通过解析BMP文件头和像素数据,实现对BMP图片的解码。
BMP图片的解码相对简单,只需按照文件格式解析头信息,提取像素数据,并根据颜色格式进行解析,即可获取图片的RGB数据。
二、图片显示方法在嵌入式Linux系统中,图片的显示可以通过多种方式实现。
LinuxC语⾔解析并显⽰.bmp格式图⽚ 1/*************************23*bmp.h⽂件45*************************/67 #ifndef __BMP_H__8#define __BMP_H__910 #include <unistd.h>11 #include <stdio.h>12 #include <stdlib.h>13 #include <fcntl.h>14 #include <string.h>15 #include <linux/fb.h>16 #include <sys/mman.h>17 #include <sys/ioctl.h>18 #include <arpa/inet.h>1920//⽂件头结构体21 typedef struct22 {23 unsigned char bfType[2]; //⽂件类型24 unsigned long bfSize; //位图⼤⼩25 unsigned short bfReserved1; //位026 unsigned short bfReserved2; //位027 unsigned long bfOffBits; //到数据偏移量28 } __attribute__((packed)) BitMapFileHeader; //使编译器不优化,其⼤⼩为14字节2930//信息头结构体31 typedef struct32 {33 unsigned long biSize; // BitMapFileHeader 字节数34 long biWidth; //位图宽度35 long biHeight; //位图⾼度,正位正向,反之为倒图36 unsigned short biPlanes; //为⽬标设备说明位⾯数,其值将总是被设为137 unsigned short biBitCount; //说明⽐特数/象素,为1、4、8、16、24、或32。
读取并在屏幕上显⽰24位bmp图像读取并在屏幕上显⽰24位bmp图像PS:本⽂⾮原创,code来⾃互联⽹。
代码如下:/*这⾥仅仅是⼀个简单的显⽰也可以写出适⽤于各种OpenGL使⽤例如设置我们甚⾄可以使⽤负的系数,使得整个图象进⾏⽔平⽅向或垂直⽅向的翻转(默认像素从左绘制到右,但翻转后将从右绘制到左。
默认像素从下绘制到上,但翻转后将从上绘制到下。
因此,*/ opengl#include#definestaticstaticstaticstaticstatic#include#includevoid{////// glClear(GL_COLOR_BUFFER_BIT);//GL_glutSwapBuffers();}int{FILE* pFile = fopen(str,exit(fseek(pFile,fread(&ImageWidth,fread(&ImageHeight,PixelLength = ImageWidth *++PixelLength;PixelLength *= ImageHeight;exit(fseek(pFile,fread(fclose(pFile);glutInit(&argc, argv);glutInitDisplayMode(GLUT_glutInitWindowPosition(glutInitWindowSize(ImageWidth, ImageHeight);glutCreateWindow(FileName);glutDisplayFunc(&display);glutMainLoop();}显⽰结果截图如下:为⽅便理解程序,下⾯把⽹上找的关于部分bmp图像格式的说明也写在下⾯了,如果还想了解的更清楚,就⾃⼰再google下,很多相关资料的。
BMP⽂件是⼀种像素⽂件,它保存了⼀幅图象中所有的像素。
这种⽂件格式可以保存单⾊位图、16⾊或256⾊索引模式像素图、24位真彩⾊图象,每种模式种单⼀像素的⼤⼩分别为1/8字节,1/2字节,1字节和3字节。
一、图片添加、加载、显示和释放在软件开发过程中,我们经常需要使用到图片,下面我们就来说说图片的加载和使用方法。
我们的SDK平台目前只支持bmp格式的图片,其他格式如jpg、png等压缩格式的图片暂时不支持。
下面我将详细讲解如何添加、加载、显示和释放一个24bit格式的文件名为plane.bmp的图片。
1添加图片资源方法由于我们的程序最终会生成mrp格式文件,因此我们需要把要显示的图片先打包到mrp文件里面。
添加文件的方法,是需要修改mpr格式的工程文件,该工程文件类似我们在Linux开发环境里的 makefile。
例如我们当前的工程文件为demo.mpr,那么我们在files组里面加入名字为plane.bmp的图片,如下图所示:当我们编译mpr工程文件的时候,如果图片被成功打包到mrp文件中,那么在编译完成的时候,会有提示信息,如下图所示:当要添加的图片不存在的时候,编译器报编译错误,如下图所示:当编译通过,并且编译输出有看到图片被成功打包进mrp包里面,说明我们完成了在mpr工程文件里面增加图片的功能。
2从mrp包里面加载图片方法我们这里说的图片加载是指在程序运行过程要显示mrp包里面的bmp图片时候,需要先将bmp加载到内存中的方法。
将bmp图片加载到内存中通常有两种方法,一种是通过调用mrc_readFileFromMrpEx函数;另一种是通过调用mrc_bitmapLoad 函数。
第一种加载图片的具体方法如下面代码所示:型如下:它的功能就是从指定的packname mrp包里面读取文件名为filename 的文件,当读取文件成功以后,通过filebuf和filelen来返回指定文件数据和数据长度,这里返回的plane.bmp文件的数据和长度,mrc_readFileFromMrpEx函数的详细使用说明可以查考mrc_base.h 文件里面的函数说明。
当mrc_readFileFromMrpEx函数调用返回成功以后,说明我们成功把plane.bmp加载到内存中,这里我们把加载的数据保存到bmp变量里面,该变量是一个T_ICON_MAP类型的指针变,参数i为图片缓冲区序号,必须是0-29,filename为预加载图片文件名称,x,y为图片加载的起始坐标,w为预加载图片的宽度,h为预加载图片高度,max_w为图片原始宽度。
在lcd上显⽰bmp图像【转载】要实现在lcd上实时显⽰usb摄像头采集的图像,前⾯已经能够采集到图像了,并保存为jpg⽂件,现在要在lcd上显⽰这个图⽚,有⼏种⽅法:⼀种是移植好minigui,然后使⽤minigui提供的函数FillBoxWithBitmap显⽰图像;⼀种是直接将图像数据写⼊framebuffer中,不管使⽤哪种前提是要把jpg⽂件解压得到RGB24数据流。
最后决定使⽤framebuffer,这样可以了解⼀些底层的东西。
这⾥先介绍如何在framebuffer上绘图,⾸先有两个结构体struct fb_fix_screeninfo 和struct fb_var_screeninfo,应⽤程序通过这两个结构体可以获取framebuffer设备相关参数。
定义两个变量struct fb_fix_screeninfo finfo;struct fb_var_screeninfo vinfo;int fb = open("/dev/fb0", O_RDWR);ioctl ( fb, FBIOGET_FSCREENINFO, &finfo)//获取与Framebuffer有关的固定的信息ioctl( fb, FBIOGET_VSCREENINFO, &vinfo)//获取与Framebuffer有关的可变信息应⽤程序中通常要⽤到struct fb_var_screeninfo的下⾯这⼏个字段:xres、yres、bits_per_pixel,分别表⽰x轴的分辨率、y轴的分辨率以及每像素的颜⾊深度(每个像素占⽤的⽐特数)。
与Framebuffer设备有关的IO通常都是通过mmap()系统调⽤来完成的。
系统调⽤mmap()⽤来实现内存映射IO。
所谓内存映射IO,是指将⼀个磁盘⽂件的内容与内存中的⼀个空间相映射。
当从这个映射内存空间中取数据时,就相当于从⽂件中读取相应的字节,⽽当向此映射内存空间写⼊数据时,就相当于向磁盘⽂件中写⼊数据。
framebuffer 编程(原创实用版)目录1.framebuffer 概述2.framebuffer 编程的基本原理3.framebuffer 编程的步骤4.framebuffer 编程的实例5.framebuffer 编程的优缺点正文【1.framebuffer 概述】Framebuffer(帧缓冲区),也被称为显存,是计算机图形学中的一种存储设备,主要用于暂时存储显卡生成的图像。
Framebuffer 是一个高分辨率的缓冲区,可以存储屏幕上的所有像素。
它主要用于将计算机生成的二维图像转换为显示器可以识别的信号,以便在屏幕上显示。
【2.framebuffer 编程的基本原理】Framebuffer 编程的基本原理是通过编程控制显卡的帧缓冲区,从而实现对图像的控制。
它主要包括以下几个步骤:1.配置 framebuffer:设置 framebuffer 的属性,如宽度、高度、颜色深度等。
2.将图像数据写入 framebuffer:通过显卡的命令将图像数据写入framebuffer。
3.提交 framebuffer:将 framebuffer 中的数据提交给显卡,开始渲染。
【3.framebuffer 编程的步骤】Framebuffer 编程的基本步骤如下:1.初始化 framebuffer:首先,需要初始化 framebuffer,包括分配内存、设置属性等。
2.绑定 framebuffer:将 framebuffer 绑定到特定的渲染管线。
3.写入图像数据:通过显卡的命令将图像数据写入 framebuffer。
4.提交 framebuffer:将 framebuffer 中的数据提交给显卡,开始渲染。
5.释放 framebuffer:渲染完成后,需要释放 framebuffer。
【4.framebuffer 编程的实例】以下是一个简单的 framebuffer 编程实例:```c#include <GL/glut.h>void display() {glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓冲区glLoadIdentity(); // 重置变换矩阵glOrtho(0, glutGet(GL_WIDTH), glutGet(GL_HEIGHT), 0, -1, 1); // 设置透视投影矩阵glBegin(GL_QUADS); // 开始绘制四边形glColor3f(1.0, 0.0, 0.0); // 设置颜色为红色glVertex2f(-0.5, -0.5); // 绘制左下角glVertex2f(0.5, -0.5); // 绘制右上角glVertex2f(0.5, 0.5); // 绘制右上角glVertex2f(-0.5, 0.5); // 绘制左上角glEnd(); // 结束绘制glFlush(); // 提交绘制结果}int main(int argc, char** argv) {glutInit(&argc, argv);glutCreateWindow("Framebuffer Programming");glutDisplayFunc(display);glutMainLoop();return 0;}```【5.framebuffer 编程的优缺点】Framebuffer 编程的优点:1.灵活性:framebuffer 编程可以实现对图像的精确控制,包括颜色、亮度、对比度等。
嵌入式Linux系统中图片解码和显示的动态加载技术在嵌入式Linux系统中,图片解码和显示是一个常见的需求。
本文将介绍一种动态加载技术,可以实现在嵌入式Linux系统中灵活地解码和显示图片。
一、嵌入式Linux系统中的图片解码技术在嵌入式Linux系统中,图片通常以二进制数据的形式存储在文件系统中。
为了将图片显示在屏幕上,需要对图片进行解码。
常见的图片格式有JPEG、PNG和BMP等。
不同的图片格式需要使用不同的解码算法。
1. JPEG图片解码JPEG是一种广泛使用的图片格式,其解码算法较为复杂。
在嵌入式Linux系统中,可以使用开源的图像处理库libjpeg来进行JPEG图片的解码。
libjpeg提供了一组API接口,可以方便地将JPEG图片解码成为RGB格式或YUV格式的图像数据。
2. PNG图片解码PNG是一种无损压缩的图片格式,其解码算法相对简单。
在嵌入式Linux系统中,可以使用开源的图像处理库libpng来进行PNG图片的解码。
libpng同样提供了一组API接口,可以方便地将PNG图片解码成为RGB格式的图像数据。
3. BMP图片解码BMP是一种简单的图片格式,其解码算法较为简单。
在嵌入式Linux系统中,可以使用开源的图像处理库libbmp来进行BMP图片的解码。
libbmp提供了一组API接口,可以将BMP图片解码成为RGB格式的图像数据。
二、嵌入式Linux系统中的图片显示技术在嵌入式Linux系统中,图片显示通常是通过显示驱动来实现。
显示驱动负责将解码后的图像数据发送给显示设备,显示设备将图像数据显示在屏幕上。
1. Framebuffer技术Framebuffer是一种常见的图形显示设备,它提供了一块连续的内存区域用于存储图像数据。
在嵌入式Linux系统中,可以通过Framebuffer设备将图像数据显示在屏幕上。
可以使用开源的framebuffer库fbi来实现在Framebuffer设备上显示图像数据。
framebuffer画bmp/** $Id: ddlist.h,v1.0 2007/8/2 09:41:16 bolidhi Exp $** heap.h: the private heap header.**Copyright(C)2006~2008bolidehi<****************>. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/mman.h>#include "lib_type.h"#include "read_bmp.h"#define BI_RGB 0x00L#define BI_RLE8 0x01L#define BI_RLE4 0x02L#define BI_BITFIELDS 0x03Ltypedef unsigned char BYTE;typedef signed char SBYTE;typedef unsigned short WORD;typedef signed short SWORD;typedef unsigned short USHORT;typedef signed short SHORT;typedef unsigned int DWORD;typedef signed int SDWORD;typedef unsigned int UINT;typedef unsigned long ULONG;typedef signed long SLONG;/*bitmap file header structure*/typedef struct _file_header file_header;struct _file_header{BYTE type[2]; //bitmap file type;DWORD size; //bitmap file size;WORD reserved1;WORD reserved2;DWORD offset;};#define FILE_HEADER_SIZE 14/*bitmap windows information head structure*/ typedef struct _info_head info_head;struct _info_head{DWORD size;DWORD width;DWORD height;WORD planes;WORD bitcount;DWORD compression;DWORD sizeimage;DWORD xpixelspermeter;DWORD ypixelspermeter;DWORD colorused;DWORD colorimportant;};#define INFO_HEAD_SIZE 40/*bitmap os2 information head structure*/typedef struct _core_head core_head;struct _core_head{DWORD size;WORD width;WORD height;WORD planes;WORD bitcount;} ;#define CORE_HEAD_SIZE 12#define wswap(x) (x)#define dwswap(x) (x)#define dwread(addr)((((unsigned char *)(addr))[0] | \ (((unsigned char *)(addr))[1] << 8) | \ (((unsigned char *)(addr))[2] << 16) | \ (((unsigned char *)(addr))[3] << 24)))#define _ROUND8(n) (((n) +7) /8)/*** read_image_buf: read image buffer to dest in specices size * @img_buf : device image buffer;* @dest :destion buffers* @size : size of reader buffer;* return the real readed size*/size_t read_image_buf(img_buffer *img_buf, void *dest, size_t size){size_t ret;if(eof_image_buf(img_buf))return 0;ret = img_buf->offset + size > img_buf->size ? img_buf->size - img_buf->offset : size;memcpy(dest, (char *)(img_buf->start)+img_buf->offset, size);//DBG_INFO("dest=%s--buf=%s--start=%d--offset=%d--size=%d\n",(char *)dest, ((char *)(img_buf->start) + img_buf->offset), (char *)(img_buf->start), img_buf->offset, (size_t)size);img_buf->offset += size;return ret;}/*** seek_image_buf: seek image buffer to dest in specices size * @img_buf : device image buffer;* @offset : seeked offset* @whence : seeked postion* return seeked postion*/int seek_image_buf(img_buffer *img_buf, size_t offset, int whence){int pos;switch(whence){case SEEK_SET:if(offset >= img_buf->size || offset < 0)return -1;img_buf->offset = offset;break;case SEEK_CUR:pos = img_buf->size + offset;if(pos >= img_buf->size || pos < 0)return -1;img_buf->offset = pos;break;case SEEK_END:pos= img_buf->size + offset - 1;if (pos >= img_buf->size || pos < 0)return -1L;img_buf->offset = pos;break;return - 1;}return img_buf->offset;}static void calc_pitch(int bpp, int width, int height, unsigned int *pitch){int linesize=0;switch(bpp){case 1:linesize = _ROUND8(width);break;case 2:linesize = _ROUND8(width << 1);break;case 4:linesize = _ROUND8(width << 2);break;case 8:linesize = width;break;case 16:linesize = width * 2;case 24:linesize = width * 3;break;case 32:linesize = width * 4;break;}*pitch = (linesize + 3) & ~3;DBG_INFO("linesize = %d--pitch=%d\n",linesize, *pitch); }static int decode_RLE8(BYTE *buf, img_buffer *img_buf) {int c, n;BYTE *p = buf;for( ;;){switch( n = getc_image_buf(img_buf)){case EOF:return 0;case 0: /* 0 = escape*/switch( n = getc_image_buf(img_buf)){case 0: /* 0 0 = end of current scan line*/case 1: /* 0 1 = end of data*/return 1;case 2: /* 0 2 xx yy delta mode NOT SUPPORTED*/ getc_image_buf(img_buf);getc_image_buf(img_buf);continue;default: /* 0 3..255 xx nn uncompressed data*/ for( c=0; c<n; c++)*p++ = getc_image_buf(img_buf);if( n & 1)getc_image_buf(img_buf);continue;}default:c = getc_image_buf(img_buf);while( n--) *p++ = c;continue;}}}static BYTE *p;static int once;static __inline void put4(int b){static int last;last = (last << 4) | b;if(++once ==2){*p ++ = last;once = 0;}}static int decode_RLE4(BYTE *buf, img_buffer *img_buf) {int c, n, c1, c2;p = buf;once = 0;c1 = 0;for (;;){switch (n = getc_image_buf(img_buf)){case EOF:return 0;case 0: /* 0 = escape */switch (n = getc_image_buf(img_buf)){case 0: /* 0 0 = end of current scan line */case 1: /* 0 1 = end of data */if (once)put4(0);return 1;case 2: /* 0 2 xx yy delta mode NOT SUPPORTED */ getc_image_buf(img_buf);getc_image_buf(img_buf);continue;default: /* 0 3..255 xx nn uncompressed data */c2 = (n + 3) & ~3;for (c = 0; c < c2; c++){if ((c & 1) == 0)c1 = getc_image_buf(img_buf);if (c < n)put4((c1 >> 4) & 0x0f);c1 <<= 4;}continue;}default:c = getc_image_buf(img_buf);c1 = (c >> 4) & 0x0f;c2 = c & 0x0f;for (c = 0; c < n; c++)put4((c & 1) ? c2 : c1);continue;}}}int read_bmp(IMAGEHEADER *image, void *buffer, size_t size) {int h, compression =0 ;int headsize;file_header fheader;info_head ihead;core_head chead;img_buffer img_buf;BYTE head_buf[INFO_HEAD_SIZE];BYTE *data = NULL;init_image_buf(&img_buf, buffer, size);if(read_image_buf(&img_buf, &head_buf, FILE_HEADER_SIZE) != FILE_HEADER_SIZE){image->type = 0;return 1;}fheader.type[0] = head_buf[0];fheader.type[1] = head_buf[1];if(*((WORD *)(&fheader.type)) != wswap(0x4D42)) //0x4D42='BM'{image->type = 0;DBG_INFO(" This is not bitmap image\n");return 1;}fheader.offset = dwswap(dwread(&head_buf[10]));if(read_image_buf(&img_buf, &headsize, sizeof(int)) != sizeof(int)){image->type =0;return 1;}headsize = dwswap(headsize);if(headsize == CORE_HEAD_SIZE){ /* read os/2 header */if(read_image_buf(&img_buf,&head_buf, CORE_HEAD_SIZE - sizeof(DWORD)) !=CORE_HEAD_SIZE - sizeof(DWORD)){return 1;}chead.width = wswap(*((WORD *)&head_buf[0]));chead.height = wswap(*((WORD *)&head_buf[2]));chead.planes = wswap(*((WORD *)&head_buf[4]));chead.bitcount = wswap(*((WORD *)&head_buf[6]));image->width = (int)chead.width;image->depth = (int)chead.height;image->bpp = chead.bitcount;compression = BI_RGB;}else{ /* read windows header */if(read_image_buf(&img_buf,&head_buf, INFO_HEAD_SIZE - sizeof(DWORD)) !=INFO_HEAD_SIZE - sizeof(DWORD)){return 1;}ihead.width = dwswap(*((DWORD*)&head_buf[0]));ihead.height = dwswap(*((DWORD*)&head_buf[4]));ihead.planes = dwswap(*((DWORD*)&head_buf[8]));ihead.bitcount = dwswap(*((DWORD*)&head_buf[10]));pression= dwswap(*((DWORD*)&head_buf[12]));ihead.sizeimage = dwswap(*((DWORD*)&head_buf[16]));ihead.xpixelspermeter = dwswap(*((DWORD*)&head_buf[20]));ihead.ypixelspermeter = dwswap(*((DWORD*)&head_buf[24]));ihead.colorused = dwswap(*((DWORD*)&head_buf[28]));ihead.colorimportant = dwswap(*((DWORD*)&head_buf[32]));image->width = (int)ihead.width;image->depth = (int)ihead.height;image->bpp = ihead.bitcount;//image->pal_size =(int)ihead.colorused;compression = pression;}if(image->bpp > 8 && image->bpp!=24){DBG_INFO("load_bmp: image bpp is not 1 4 8 or 24\n");return 1;}/*compreession = IMG_BGR;image->planes = 1;*///image->type = IMAGE_TYPE_BMP;calc_pitch(image->bpp, image->width, image->depth, &image->bytewidth);/* Allocate image */image->data =(BYTE*) malloc(image->bytewidth * image->depth);if(image->data == NULL){DBG_INFO(" Allocate image data failed\n");goto err;}#if 0if(image->bpp <= 8){image->pal_tabs =(palette *)malloc(image->pal_size * sizeof(palette));if(!image->pal_tabs) goto err;/* get colormap*/for(i =0; i<image->pal_size;i++){image->pal_tabs[i].b = getc_image_buf(&img_buf);image->pal_tabs[i].g = getc_image_buf(&img_buf);image->pal_tabs[i].r = getc_image_buf(&img_buf);if(headsize !=CORE_HEAD_SIZE) getc_image_buf(&img_buf);}}#endif/* decode image data*/seek_image_buf(&img_buf, fheader.offset, SEEK_SET);h = image->depth;//data = image->data + (h-1)* image->bytewidth ; data = image->data;switch(compression){case BI_RLE8:while(--h>=0){if(!decode_RLE8(data, &img_buf))break;//data -= image->bytewidth ;data += image->bytewidth ;}break;case BI_RLE4:while(--h>=0){if(!decode_RLE4(data, &img_buf))break;//data -= image->bytewidth ;data += image->bytewidth ;}break;default:while(--h>=0){//DBG_INFO("---width=%d---\n",image->bytewidth);if(read_image_buf(&img_buf, data, image->bytewidth) != image->bytewidth)goto err;//data -= image->bytewidth ;data += image->bytewidth ;}break;}return 0;err:DBG_INFO("loadbmp:load image error\n");if(image->data){free(image->data);}/*if(image->pal_tabs){free(image->pal_tabs);image->pal_size = 0;}*/return 1;}int cetc_renderbmp(IMAGEHEADER *p_img, const char *filename){int fd;struct stat st;void *buff;int ret;DBG_INFO( "Enter \n");if(filename !=NULL && *filename !='\0'){fd = open(filename, O_RDONLY, 0);if(fd == -1){DBG_INFO(" Open file %s failed\n", filename);return 1;}if(0 != fstat(fd, &st)){DBG_INFO(" Get fd %d stat information failed\n", fd);return 1;}buff = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);if((int)buff == -1){DBG_INFO(" mmap the fd %d failed\n", fd);return 1;}ret = read_bmp(p_img, buff, st.st_size);// DBG_INFO("p_img->data=%s\n",p_img->data); munmap(buff, st.st_size);close(fd);return ret;}DBG_INFO(" Leave\n");return 1;}。
用c语言读取并显示bmp图像如何在WIN-TC中或TC++3.0中把一张BMP格式的图片显示出来?下面的是<>随书光盘上的代码,我在TC2.0下编译通过.它是利用了抖动技术显示了8bit和24bit的位图(也就是256色和16M色位图),应该能满足你的需要.不过,我想问下,你老师教过抖动显示吗?#include#include#include#include#define NoError 0#define ErrorFileOpen 1#define ErrorFileType 2#define ErrorImageColor 3typedef struct tagBITMAPFILEHEADER{unsigned int bfType;unsigned long bfSize;unsigned int bfReserved1;unsigned int bfReserved2;unsigned long bfoffBits;}BITMAPFILEHEADER;typedef struct tagBITMAPINFOHEADER{unsigned long biSize;unsigned long biWidth;unsigned long biHeight;unsigned int biPlanes;unsigned int biBitCount;unsigned long biCompression;unsigned long biSizeImage;unsigned long biXPelsPerMeter;unsigned long biYPelsPerMeter;unsigned long biClrUsed;unsigned long biClrImportant;} BITMAPINFOHEADER;typedef struct tagRGBQUAD{unsigned char rgbBlue;unsigned char rgbGreen;unsigned char rgbRed;unsigned char rgbReserved;} RGBQUAD;unsigned char PalReg[17]= { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0}; unsigned char StandardPal[48]= {0, 0, 0, 32, 0, 0, 0,32, 0, 32,32, 0, 0, 0,32, 32, 0,32, 0,32,32, 32,32, 32, 48, 48,48, 63, 0, 0, 0,63, 0, 63,63, 0, 0, 0,63, 63, 0,63, 0,63,63, 63,63,63, };unsigned char LightnessMatrix [16][16]= {{ 0,235,59,219,15,231,55,215,2,232,56,217,12,229,52,213},{128,64,187,123,143,79,183,119,130,66,184,120,140,76,180,1 16},{33,192,16,251,47,207,31,247,34,194,18,248,44,204,28,244}, {161,97,144,80,175,111,159,95,162,98,146,82,172,108,156,92 },{8,225,48,208,5,239,63,223,10,226,50,210,6,236,60,220},{136,72,176,112,133,69,191,127,138,74,178,114,134,70,188,124},{41,200,24,240,36,197,20,255,42,202,26,242,38,198,22,252}, {169,105,152,88,164,100,148,84,170,106,154,90,166,102,150, 86},{3,233,57,216,13,228,53,212,1,234,58,218,14,230,54,214},{131,67,185,121,141,77,181,117,129,65,186,122,142,78,182,1 18},{35,195,19,249,45,205,29,245,32,193,17,250,46,206,30,246}, {163,99,147,83,173,109,157,93,160,96,145,81,174,110,158,94 },{11,227,51,211,7,237,61,221,9,224,49,209,4,238,62,222},{139,75,179,115,135,71,189,125,137,73,177,113,132,68,190,1 26},{43,203,27,243,39,199,23,253,40,201,25,241,37,196,21,254}, {171,107,155,91,167,103,151,87,168,104,153,89,165,101,149, 85},};unsigned char ColorTable[2][2][2]= {{{0,12},{10,14}},{{9,13},{11,15}}}; unsigned char ColorMap[256][3];int ShowBmp(char *FileName);int GetColor(unsigned char R,unsigned char G, unsigned char B,int X,int Y); void SetVideoMode(unsigned char Mode);void SetPalReg(unsigned char *palReg);void SetDacReg(unsigned char *DacReg, int Color, int Count);void PutPixel(int X, int Y, unsigned char Color);/* 主函数*/void main (int argc, char *argv[]){if(argc!=2){printf("Usage:\tSHOW Filename.BMP\n");exit(1);}ShowBmp(argv[1]);}/* 根据图像文件名,读取图像内容并利用抖动技术进行显示*/ int ShowBmp(char *FileName){FILE *Fp;BITMAPFILEHEADER FileHead;BITMAPINFOHEADER InfoHead;RGBQUAD RGB;int N, W,Y,X,C,Color;unsigned char Buffer[4096];Fp=fopen(FileName,"rb");if (Fp==NULL)return(ErrorFileOpen);fread(&FileHead,sizeof(BITMAPFILEHEADER),1,Fp);if(FileHead.bfType!='BM'){fclose(Fp);return(ErrorFileType);}fread(&InfoHead,sizeof(BITMAPINFOHEADER),1,Fp);if(InfoHead.biBitCount!=8 && InfoHead.biBitCount!=24){fclose(Fp);return(ErrorImageColor);}/* 设置显示模式和显示区域*/SetVideoMode(0x12);SetPalReg(PalReg);SetDacReg(StandardPal,0,16);/* 对两种不同色彩数的图像分别进行处理*/if(InfoHead.biBitCount==8) /* 256色*/{for (N=0;N<256;N++){fread(&RGB, sizeof(RGBQUAD),1,Fp);ColorMap[N][0]=RGB.rgbRed;ColorMap[N][1]=RGB.rgbGreen;ColorMap[N][2]=RGB.rgbBlue;}W=(InfoHead.biWidth+3)/4*4;for(Y=InfoHead.biHeight-1;Y>=480;Y--)fread(Buffer,sizeof(unsigned char),W,Fp);for(;Y>0;Y--){fread(Buffer,sizeof(unsigned char),W,Fp);for (X=0;X<640;x++)<="">{C=Buffer[X];Color=GetColor(ColorMap[C][0],ColorMap[C][1],ColorMap[ C][2],X,Y); PutPixel (X,Y,Color);}}}else /* 24bits真彩色*/{W=(InfoHead.biWidth*3+3)/4*4;for(Y=InfoHead.biHeight-1;Y>639;Y--)fread(Buffer,sizeof(unsigned char),W,Fp);for(;Y>=0;Y--){fread(Buffer,sizeof(unsigned char),W,Fp);for(X=0;X<640;x++)<="">{C=X*3;Color=GetColor(Buffer[C+2],Buffer[C+1],Buffer[C],X,Y);PutPixel(X,Y,Color);}}}getch();fclose(Fp);SetVideoMode(0x03);return(NoError);}int GetColor(unsigned char R, unsigned char G, unsigned char B, int X, int Y) {unsigned int L=LightnessMatrix[Y & 0x0F][X & 0x0F];return(ColorTable[(unsigned int)R*256/255>L][(unsigned int)G*256/255>L][(unsigned int)B*256/255>L]); }void SetVideoMode(unsigned char Mode){_AH=0x00;_AL=Mode;geninterrupt(0x10);}void SetPalReg(unsigned char *PalReg){_ES=FP_SEG((unsigned char far*)PalReg);_DX=FP_OFF((unsigned char far*)PalReg);_AX=0x1002;geninterrupt(0x10);}void SetDacReg(unsigned char *DacReg,int Color,int Count) {_ES=FP_SEG((unsigned char far*)DacReg);_DX=FP_OFF((unsigned char far*)DacReg);_AX=0x1012;_BX=Color;_CX=Count;geninterrupt(0x10);}/* 在对应位置显示像素色彩*/void PutPixel(int X, int Y, unsigned char Color){_AH=0x0C;_AL=Color;_CX=X;_DX=Y;geninterrupt(0x10);}16色位图的显示文:吴进/Luckylai对于象大家常用TC的16色图形模式编程的初学者,如果能在程序里使用图片那就会方便很多了,以前在TC256上看见吴进写的《TC 的16色BMP闪电显示(66k) 》的代码,发现写的的确不错,而且绝对能在TC的initgraph()初始化的BGI模式下使用。
如何在嵌入式Linux系统中实现图片解码和显示嵌入式Linux系统中的图片解码和显示是一个在现代嵌入式系统中非常常见和重要的功能。
在许多嵌入式应用中,如智能家居、工业自动化或医疗设备等,图像处理是必不可少的。
本文将介绍如何在嵌入式Linux系统中实现图片解码和显示的方法和技术。
一、嵌入式Linux系统概述嵌入式Linux系统是运行在嵌入式设备上的一种精简型操作系统。
与传统的桌面操作系统相比,嵌入式Linux系统具有体积小、资源占用低以及可裁剪性强等特点,非常适用于资源有限的嵌入式设备。
二、图片解码和显示的原理在嵌入式Linux系统中,图片解码和显示涉及到两个主要的过程:图片解码和图像显示。
1. 图片解码图片解码是将存储在文件或内存中的图像数据转换为可供显示的像素数据的过程。
常见的图像格式包括JPEG、PNG和BMP等。
在嵌入式Linux系统中,可以使用各种图像解码库来实现图片解码功能,如libjpeg、libpng和libbmp等。
这些库提供了一组API函数,通过这些函数可以将图像数据解码为像素数据。
2. 图像显示图像显示是将解码后的像素数据在屏幕上显示出来的过程。
在嵌入式Linux系统中,可以使用FrameBuffer(帧缓冲)来实现图像的显示。
FrameBuffer是一种位图显示设备,可以直接访问和控制显存,并将像素数据显示在屏幕上。
通过FrameBuffer,可以将解码后的像素数据写入显存,并通过控制硬件来在屏幕上显示图像。
三、实现图片解码和显示的步骤要在嵌入式Linux系统中实现图片解码和显示功能,可以按照以下步骤进行:1. 配置嵌入式Linux系统首先,需要在嵌入式Linux系统中配置和编译相应的图像解码库和FrameBuffer驱动。
可以根据具体的硬件平台和系统配置来选择和设置相应的驱动程序和库文件。
2. 加载图像数据将需要解码和显示的图像数据加载到内存中。
可以从文件系统中读取图像数据,或者通过网络或其他外部接口获取图像数据。
一、BMP:包括BITMAPFILEHEADER(位图文件头)、BITMAPINFOHEADER(位图信息头)、Palette(调色板)、ImageData(位图数据)构成。
DDB:是设备相关位图文件,结构如下:Typedef struct tagBITMAP{Int bmType;//通常为0Int bmWidth;//像素点宽度Int bmHeight;//像素点高度Int bmWidthBytes;//每行数据的字节数,必为偶数BYTE bmPlanes;//显示设备的色位面数BYTE bmBitsPixel;//每像素的位数V oid FAR *bmBits;//指向像素数据的指针};位图必须在同类设备中显示,并且此设备在位平面或彩色上与原设备有同样的色彩安排,否则色彩可能完全失真。
DIB是设备无关位图文件,由3部分构成:BITMAPINFOHEADER(位图信息头)、Palette(调色板)、ImageData(位图数据)。
它的结构和BMP文件结构相似,它实际就是BMP文件去掉BITMAPFILEHEADER(位图文件头),即一个BITMAPINFOHEADER(位图信息头)结构后面接上调色板再加上图像数据。
BMP文件有两种显示方法,首先将BMP文件读成DIB格式,当显示时,一种是直接将DIB 显示,另一种是将DIB转化为DDB,再显示DDB。
几个数据类型:Cfile LPCTSTR UINT几个函数:1、virtual BOOL Open(LPCTSTR lpszFileName,UINT nOpenFlags, CFileException*pError=NULL);Return Value:Nonzero if the open was successful; otherwise 0. The pError parameter is meaningful only if 0 is returned.LpszFileName:A string that is the path to the desired file.NOpenFlags:defines the file’s sharing and access mode. It specifies the action to take when opening the file.PError:A pointer to an existing file-exception object that will receive the status of a failed operation.如:Open(filename,CFile::modeRead|CFile::shareDenyNone,NULL)==0)2、int AfxMessageBox(LPCTSTR lpszText,UINT nType=MB_OK,UINT nIDHelp=0);3、The HeapAlloc function allocates a block of memory from a heap. The allocated memory is not movable.LPVOID HeapAlloc(HANDLE hHeap, // handle to the private heap blockDWORD dwFlags, // heap allocation control flagsDWORD dwBytes // number of bytes to allocate);4、memcpy:Copies characters between buffers5、HeapFree:frees a memory block allocated from a heap by the HeapAlloc or HeapReAlloc function.6、SetDIBitsToDevice:sets the pixels in the specified rectangle on the device that is associated with the destination device context using color data from adevice-independent bitmap (DIB).int SetDIBitsToDevice(HDC hdc, // handle to device contextint XDest, // x-coordinate of upper-left corner of// dest. rect.int YDest, // y-coordinate of upper-left corner of// dest. rect.DWORD dwWidth, // source rectangle widthDWORD dwHeight, // source rectangle heightint XSrc, // x-coordinate of lower-left corner of// source rect.int YSrc, // y-coordinate of lower-left corner of// source rect.UINT uStartScan, // first scan line in arrayUINT cScanLines, // number of scan linesCONST VOID *lpvBits, // address of array with DIB bitsCONST BITMAPINFO *lpbmi, // address of structure with bitmap info.UINT fuColorUse // RGB or palette indexes);二、新建一多(单)文档应用程序Getbmp三、在*Doc.h中添加几个变量:BITMAPFILEHEADER bf;//文件头BITMAPINFOHEADER bi;//信息头RGBQUAD *quad; //调色板BYTE *lpBuf; //图像数据BITMAPINFO *pbi;int flag; //标志是否打开了bmp文件int numQuad; //调色板数目四、对C*Doc类添加消息处理函数:OnOpenDocument()CString filename;CFile file;//打开文件对话框filename=lpszPathName;if (file.Open(filename,CFile::modeRead|CFile::shareDenyNone,NULL)==0){//读取文件失败AfxMessageBox("无法打开文件!",MB_OK,0);return 1;}//读取文件头file.Read(&bf,sizeof(bf));if(bf.bfType!=0x4d42) //"BM"{AfxMessageBox("非BMP文件!",MB_OK,0);return 1;}//判断文件是否损坏if (file.GetLength()!=bf.bfSize){AfxMessageBox("文件已损坏,请检查!",MB_OK,0);return 1;}//读取文件信息头file.Read(&bi,sizeof(bi));//计算调色板数目numQuad=0;if (bi.biBitCount<24){numQuad=1<<bi.biBitCount;}//为图像信息pbi申请空间pbi=(BITMAPINFO*)HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER) +numQuad*sizeof(RGBQUAD));memcpy(pbi,&bi,sizeof(bi));quad=(RGBQUAD*)(BYTE*)pbi+sizeof(BITMAPINFOHEADER);//读取调色板if (numQuad!=0){file.Read(quad,sizeof(RGBQUAD)*numQuad);}//为图像数据申请空间bi.biSizeImage=bf.bfSize-bf.bfOffBits;lpBuf=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage);//读取图像数据file.Read(lpBuf,bi.biSizeImage);//图像读取完毕,关闭文件,设置标志file.Close();flag=1;return TRUE;五、C*View类的OnPaint()函数://得到文档指针CGetbmpDoc *pDoc=GetDocument();ASSERT_V ALID(pDoc);//是否已打开一BMP文件if (pDoc->flag==1){SetDIBitsToDevice(dc.m_hDC, //DIB将输出的设备描述表0, //设备描述表中位图输出起始逻辑x坐标0, //设备描述表中位图输出起始逻辑y坐标pDoc->bi.biWidth, //DIB的宽度pDoc->bi.biHeight, //DIB的高度0, //DIB开始读取输出的像素数据的x位置0, //DIB开始读取输出的像素数据的y位置0, //DIB中像素的水平行号,它对应lpBits内存缓冲区第一行数据pDoc->bi.biHeight, //DIB的行数,对应包含在由lpBits所指内存缓冲区中的数据pDoc->lpBuf, //包含像素数据的内存缓冲区的指针pDoc->pbi, //指向初始化了的BITMAPINFO数据结构的指针,描述了位图的大小和色彩数据DIB_RGB_COLORS); //制定时显示的颜色}Invalidate(FALSE);六、释放内存:(Cdoc类的析构函数:)CGetbmpDoc::~CGetbmpDoc(){if(flag==1){HeapFree(GetProcessHeap(),0,pbi);HeapFree(GetProcessHeap(),0,lpBuf);}}。
一个简单的显示一幅bmp图片的程序上周我做一个简单的显示一幅bmp图片的程序。
下面我就简单介绍一下这个程序。
首先建一个单文档程序,名字就叫:ShowBmp. 添加如下代码:1. 在CShowBmpView中添加两个成员变量:CString m_FilePath; //用于存贮bmp图片的路径bool m_AllowShowBmp;//用于判断是否显示bmp图片的变量2. 在CShowBmpView中添加ID_FILE_OPEN的Command消息,对应的函数是OnFileOpen()。
在OnFileOpen()函数里添加如下代码:void CShowBmpView::OnFileOpen(){// TODO: Add your command handler code hereCFileDialog dlg(TRUE); //定义一个文件对话框/*dlg.DoModal()为弹出对话框,dlg.DoModal()==IDOK为假如单击确定*/if(dlg.DoModal()==IDOK){m_FilePath = dlg.GetPathName(); //取得文件路径及文件名/*假如文件的扩展名不是.bmp,则弹出对话框提示出错*/if(dlg.GetFileExt()!="bmp"){AfxMessageBox("此文件不是bmp文件",MB_ICONERROR);return;}m_AllowShowBmp = TRUE; //允许显示bmp图片Invalidate(); //重绘客户区}}3. 在CShowBmpView的OnDraw函数里添加如下代码:void CShowBmpView::OnDraw(CDC* pDC){CShowBmpDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// TODO: add draw code for native data hereif(m_AllowShowBmp) //假如允许显示bmp图片{CBitmap bitmap; //定义一个位图类变量/*从文件中装入位图*/HBITMAP chbitmap = (HBITMAP)LoadImage(NULL, //如果从资源加载,则指明包含位图资源的程序实例句柄m_FilePath,//位图文件路径(含文件名)IMAGE_BITMAP,//加载的图像类型为位图0,0, //宽度和高度,0表示使用默认值LR_LOADFROMFILE); //加载标志,表明从文件加载bitmap.Attach(chbitmap);/*创建一个兼容DC*/CDC dcComp;dcComp.CreateCompatibleDC(pDC);/*将位图选入兼容DC中*/dcComp.SelectObject(&bitmap);BITMAP bminfo; //定义位图信息结构体变量bitmap.GetObject(sizeof(bminfo),&bminfo);//取得位图信息pDC->BitBlt(//显示位置,即最左上角的位置,你可以把这个变为100,100,看看有什么效果0,0,bminfo.bmWidth,bminfo.bmHeight,//显示位图的宽度和高度&dcComp, //位图所在的兼容DC0,0, //兼容DC中的位置SRCCOPY); //显示方式,表示直接复制DeleteObject(bitmap); // 释放位图所占用的资源}}4. 对工程编译运行。
嵌入式Linux系统中图片解码和显示的快速入门教程嵌入式Linux系统在当今的物联网、智能设备以及嵌入式应用领域中被广泛应用。
其中,图片解码和显示是嵌入式设备中常见的功能需求之一。
本教程将通过以下几个方面介绍嵌入式Linux 系统中图片解码和显示的快速入门方法。
一、概述图片解码与显示是指将图片文件进行解码处理,并在嵌入式设备的显示屏幕上显示出来。
对于嵌入式Linux系统而言,图片解码和显示一般涉及到以下几个关键步骤:1. 图片读取:从存储介质中读取图片文件数据。
2. 图片解码:将读取到的图片数据解码成位图格式。
3. 图片显示:将解码后的位图数据在显示设备上呈现。
二、图片解码在嵌入式Linux系统中,常见的图片格式有JPEG、PNG、BMP等。
针对不同格式的图片,我们需要选择相应的解码库进行解码处理。
以JPEG格式图片为例,常用的解码库有libjpeg和OpenCV等。
以下是使用libjpeg库进行JPEG图片解码的示例代码:```c#include <stdio.h>#include <jpeglib.h>int main() {FILE *fp;struct jpeg_decompress_struct cinfo;struct jpeg_error_mgr jerr;fp = fopen("example.jpg", "rb");if (fp == NULL) {perror("Failed to open file");return 1;}cinfo.err = jpeg_std_error(&jerr);jpeg_stdio_src(&cinfo, fp);jpeg_read_header(&cinfo, TRUE);jpeg_start_decompress(&cinfo);int width = cinfo.image_width;int height = cinfo.image_height;int numChannels = cinfo.num_components; // 图片通道数,一般为3(RGB)unsigned char *imageData = (unsigned char *) malloc(width * height * numChannels);unsigned char *rowPointer[1];while (cinfo.output_scanline < cinfo.output_height) {rowPointer[0] = imageData + (cinfo.output_scanline * width * numChannels);jpeg_read_scanlines(&cinfo, rowPointer, 1);}jpeg_destroy_decompress(&cinfo);fclose(fp);// 解码后的位图数据保存在imageData数组中,可以根据实际需求进行处理return 0;}```三、图片显示在图片解码完成后,我们需要将解码后的位图数据在嵌入式Linux设备的显示屏上显示出来。
通过写framebuffer显示BMP图片2010-03-23 17:00这段时间一直在搞触摸屏的相关工作,调完驱动后,老大要我再做个校准程序,这个校准程序要在开机时就运行,这个程序其实只会执行这一次,因为在上层还会用JA V A写一个校准程序。
暂不说校准本身,就说提示语吧,本来画几个十字架就OK了,或者再做个英文提示,就执行一次吗,但是老大还是要我学着输出中文提示,校准程序在Android刚开机还没有开启其它任务时就要运行,此时还不支持中文字库,于是我就偷个懒向framebuffer中写了张图片,!下面的程序是从同事那拷来的,原程序出处就不知道了!改了改就能用了,挺好!#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <string.h>#include <linux/fb.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <arpa/inet.h>//14byte文件头typedef struct{char cfType[2];//文件类型,"BM"(0x4D42)long cfSize;//文件大小(字节)long cfReserved;//保留,值为0long cfoffBits;//数据区相对于文件头的偏移量(字节)}__attribute__((packed)) BITMAPFILEHEADER;//__attribute__((packed))的作用是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐//40byte信息头typedef struct{char ciSize[4];//BITMAPFILEHEADER所占的字节数long ciWidth;//long ciHeight;//char ciPlanes[2];//目标设备的位平面数,值为1int ciBitCount;//每个像素的位数char ciCompress[4];//压缩说明char ciSizeImage[4];//用字节表示的图像大小,该数据必须是4的倍数char ciXPelsPerMeter[4];//目标设备的水平像素数/米char ciYPelsPerMeter[4];//目标设备的垂直像素数/米char ciClrUsed[4]; //位图使用调色板的颜色数char ciClrImportant[4]; //指定重要的颜色数,当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要}__attribute__((packed)) BITMAPINFOHEADER;typedef struct{unsigned short red:5;unsigned short green:6;unsigned short blue:5;}__attribute__((packed)) PIXEL;//颜色模式,RGB565BITMAPFILEHEADER FileHead;BITMAPINFOHEADER InfoHead;static char *fbp = 0;static int xres = 0;static int yres = 0;static int bits_per_pixel = 0;int show_bmp();int main ( int argc, char *argv[] ){int fbfd = 0;struct fb_var_screeninfo vinfo;struct fb_fix_screeninfo finfo;long int screensize = 0;//打开显示设备fbfd = open("/dev/graphics/fb0", O_RDWR);if (!fbfd){printf("Error: cannot open framebuffer device.\n");exit(1);}if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)){printf("Error:reading fixed information.\n");exit(2);}if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)){printf("Error: reading variable information.\n");exit(3);}printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );xres = vinfo.xres;yres = vinfo.yres;bits_per_pixel = vinfo.bits_per_pixel;//计算屏幕的总大小(字节)screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;printf("screensize=%d\n",screensize);//内存映射fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); if ((int)fbp == -1){printf("Error: failed to map framebuffer device to memory.\n");exit(4);}printf("sizeof header=%d\n", sizeof(BITMAPFILEHEADER));printf("into show_bmp function\n");show_bmp();munmap(fbp, screensize);close(fbfd);return 0;}int show_bmp(){FILE *fp;int rc;int line_x, line_y;long int location = 0, BytesPerLine = 0;char tmp[1024*10];fp = fopen( "./calibration.bmp", "rb" );if (fp == NULL){return( -1 );}rc = fread( &FileHead, sizeof(BITMAPFILEHEADER),1, fp );if ( rc != 1){printf("read header error!\n");fclose( fp );return( -2 );}if (memcmp(FileHead.cfType, "BM", 2) != 0){printf("it's not a BMP file\n");fclose( fp );return( -3 );}rc = fread( (char *)&InfoHead, sizeof(BITMAPINFOHEADER),1, fp );if ( rc != 1){printf("read infoheader error!\n");fclose( fp );return( -4 );}//跳转的数据区fseek(fp, FileHead.cfoffBits, SEEK_SET);//每行字节数BytesPerLine = (InfoHead.ciWidth * InfoHead.ciBitCount + 31) / 32 * 4;line_x = line_y = 0;//向framebuffer中写BMP图片while(!feof(fp)){PIXEL pix;unsigned short int tmp;rc = fread( (char *)&pix, 1, sizeof(unsigned short int), fp);if (rc != sizeof(unsigned short int)){break;}location = line_x * bits_per_pixel / 8 + (InfoHead.ciHeight - line_y - 1) * xres * bits_per_pixel / 8;//显示每一个像素tmp=pix.red<<0 | pix.green<<5 | pix.blue<<11;*((unsigned short int*)(fbp + location)) = tmp;line_x++;if (line_x == InfoHead.ciWidth ){line_x = 0;line_y++;if(line_y == InfoHead.ciHeight){break;}}}fclose( fp );return( 0 );}。