8位灰度图在LCD上显示
一、概述
1、灰度
灰度使用黑色调表示物体,即用黑色为基准色,不同的饱和度的黑色来显示图像。每个灰度对象都具有从 0%(白色)到灰度条100%(黑色)的亮度值。 使用黑白或灰度扫描仪生成的图像通常以灰度显示。
像素值量化后用一个字节(8 bits)来表示。如把有黑-灰-白连续变化的灰度值量化为256个灰度级,灰度值的范围为0~255,表示亮度从深到浅,对应图像中的颜色为从黑到白。黑白照片包含了黑白之间的所有的灰度色调,每个像素值都是介于黑色和白色之间的256种灰度中的一种。
2、灰度图
用灰度表示的图像称作灰度图,灰度图的RGB三通道满足关系式:R=G=B。
3、灰度图bmp文件格式
|
偏移量 |
域的名称 |
大小 |
内容 |
|
|
图像文件头 |
0000h |
标识符(Identifier) |
2 bytes |
两字节的内容用来识别位图的类型: ‘BM’ : Windows 3.1x, 95, NT, … |
|
0002h |
File Size |
1 dword |
用字节表示的整个文件的大小 |
|
|
0006h |
Reserved |
1 dword |
保留,设置为0 |
|
|
000Ah |
Bitmap Data Offset |
1 dword |
从文件开始到位图数据开始之间的数据 (bitmap data)之间的偏移量 |
|
|
000Eh |
Bitmap Header Size |
1 dword |
位图信息头(Bitmap Info Header)的长度,用来描述 位图的颜色、压缩方法等。下面的长度表示: 28h - Windows 3.1x, 95, NT, 0Ch - OS/2 1.x F0h - OS/2 2.x … |
|
|
0012h |
Width |
1 dword |
位图的宽度,以像素为单位 |
|
|
0016h |
Height |
1 dword |
位图的高度,以像素为单位 |
|
|
001Ah |
Planes |
1 word |
位图的位面数 |
|
|
图像信息头
|
001Ch |
Bits Per Pixel |
1 word |
每个像素的位数 1 - Monochrome bitmap 4 - 16 color bitmap 8 - 256 color bitmap 16 - 16bit (high color) bitmap 24 - 24bit (true color) bitmap 32 - 32bit (true color) bitmap |
|
001Eh |
Compression |
1 dword |
压缩说明: 0 - none (也使用BI_RGB表示) 1 - RLE 8-bit / pixel (也使用BI_RLE4表示) 2 - RLE 4-bit / pixel (也使用BI_RLE8表示) 3 - Bitfields (也使用BI_BITFIELDS表示) |
|
|
0022h |
Bitmap Data Size |
1 dword |
用字节数表示的位图数据的大小。该数必须是4的倍数 |
|
|
0026h |
HResolution |
1 dword |
用像素/米表示的水平分辨率 |
|
|
002Ah |
VResolution |
1 dword |
用像素/米表示的垂直分辨率 |
|
|
002Eh |
Colors |
1 dword |
位图使用的颜色数。如8-位/像素表示为100h或者 256. |
|
|
0032h |
Important Colors |
1 dword |
指定重要的颜色数。当该域的值等于颜色数时,表示所有 颜色都一样重要 |
|
|
调色板数据 |
0036h |
Palette |
N * 4 byte |
调色板规范。对于调色板中的每个表项,这4个字节用下述 方法来描述RGB的值:
|
|
图像数据 |
0436h |
Bitmap Data |
x bytes |
该域的大小取决于压缩方法,它包含所有的位图数据字节 ,这些数据实际就是彩色调色板的索引号 |
example: gray.bmp
1)gray.bmp的图片信息


2)grap.bmp文件的数据

0000h: 标示符为“BM”
0002h: 文件大小为0x13036,也就是77878字节
0006h: 保留
000Ah:从文件开头到位图数据开始的偏移量为0x436
000Eh: 位图信息头的长度为0x28
0012h: 位图的宽度为0x140,也就是宽320个像素
0016h: 位图的高度为0xF0,也就是高为240个像素
001Ah: 位图为1帧
001Ch:像素的位数为8位
001Eh: 图片无压缩
0022H: 位图数据的大小为0x12C00,也就是76800个字节
0026H: 水平分辨率为7200
002Ah: 垂直分辨率为7200
002Eh: 位图使用的颜色数--该域并未赋值
0032h: 重要的颜色数--该域并未赋值
0036h-0435h: 调色板数据
0436h: 位图数据区
3)解读
位图数据区保存的是图片有效的数据,一个字节的存储单元对应图片的一个像素,一个字节的数值代表了对应像素的灰度值。本例图片是宽320*高240,位图数据区为76800个字节,算上头部的控制块为1078个字节,文件总大小为77878字节。
在显示的时候,从位图数据区读取数据,获得一个像素的灰度值后,就以灰度值为索引,从调色板区找出灰度值对应的rgb,然后再显示屏上显示出该像素。
☆ 注意
windows规定一个扫描行所占的字节数必须是4的倍数,不足的以0填充。假设一个图片款318个像素,实际上一行占据了320个字节。
4) bmp文件存储灰度图像的顺序
bmp文件存储图像的顺序是左下角-->右上角,也就是“从下到上,从左到右”。
那么在显示bmp图像时也要遵循这样的顺序,即是:由下而上,由左到右。倘若安装"从上到下,从左到右",那么显示的图像实际上是关于Y轴翻转的。
测试bmp文件:

WinHex中对应的内容:

二、8位灰度格式转换到16位565RGB的格式
灰度图的RGB通道满足:R=G=B,以灰度值替换RGB三个通道就得到RGB格式的数据。考虑到LCD显示器的显示格式是5:6:5(r:g:b),而灰度值是8位灰阶,所以有如下的转换计算公式:
r = GrayValue/256 * 32 = GrayValue/8 = GrayValue >> 3
g = GrayValue/256 * 64 = GrayValue/4 = GrayValue >> 2
b = GrayValue/256 * 32 = GrayValue/8 = GrayValue >> 3
8位灰度值转换为16位的RGB公式为:
#define GRAYTORGB16(t) ((t >> 3)|((t & ~3) << 3)|((t & ~7) << 8))
三、测试程序代码
/**
* @brief 显示灰度图
* @param x,y : 显示在LCD上的坐标
* pic_name: 存储在SD卡根目录下的灰度文件名
* @retval None
*/
void Lcd_show_bmp(unsigned short int x, unsigned short int y,char *pic_name)
{
int i, j;
int width, height, l_width;
BITMAPFILEHEADER bitHead;
BITMAPINFOHEADER bitInfoHead;
WORD fileType;
unsigned int read_num; f_mount(, &bmpfs[]);
BMP_DEBUG_PRINTF("file mount ok \r\n");
bmpres = f_open( &bmpfsrc , (char *)pic_name, FA_OPEN_EXISTING | FA_READ); if(bmpres == FR_OK)
{
BMP_DEBUG_PRINTF("Open file success\r\n"); /* 读取文件头信息 两个字节*/
f_read(&bmpfsrc,&fileType,sizeof(WORD),&read_num); /* 判断是不是bmp文件 "BM"*/
if(fileType != 0x4d42)
{
BMP_DEBUG_PRINTF("file is not .bmp file!\r\n");
return;
}
else
{
BMP_DEBUG_PRINTF("Ok this is .bmp file\r\n");
} /* 读取BMP文件头信息*/
f_read(&bmpfsrc,&bitHead,sizeof(tagBITMAPFILEHEADER),&read_num);
showBmpHead(&bitHead); /* 读取位图信息头信息 */
f_read(&bmpfsrc,&bitInfoHead,sizeof(BITMAPINFOHEADER),&read_num);
showBmpInforHead(&bitInfoHead);
}
else
{
BMP_DEBUG_PRINTF("file open fail!\r\n");
return;
} width = bitInfoHead.biWidth;
height = bitInfoHead.biHeight; /* 计算位图的实际宽度并确保它为4的倍数 */
l_width = WIDTHBYTES(width);
if(l_width > )
{
BMP_DEBUG_PRINTF("\n SORRY, PIC IS TOO BIG (<=320)\n");
return;
} /* 设置Lcd Gram 扫描方向为: 右下角-> 左上角 */
Lcd_GramScan(); /* 开一个图片大小的窗口*/
LCD_OpenWindow(x, y, width, height); /* 判断是否是8bit灰度图 */
if(bitInfoHead.biBitCount == )
{
f_lseek(&bmpfsrc,0x0436); for(i=;i< height; i++)
{
/* 读取一行bmp的数据到数组pColorData里面 */
f_read(&bmpfsrc,pColorData,l_width,&read_num); for(j=; j<width; j++) //一行有效信息
{
unsigned short d;
d = pColorData[j];
LCD_WR_Data(GRAYTORGB16(d)); //写入LCD-GRAM
}
}
}
else
{
BMP_DEBUG_PRINTF("SORRY, THIS PIC IS NOT A 8BITS GRAY Picture!");
return ;
}
f_close(&bmpfsrc);
}
参考资料:bmp头文件和8 bit 灰度图的显示
《STM32库开发实战指南》
8位灰度图在LCD上显示的更多相关文章
- 30、在LCD上显示摄像头图像
1. 准备虚拟机2.安装工具链sudo tar xjf arm-linux-gcc-4.3.2.tar.bz2 -C /设置环境变量:sudo vi /etc/environment : PATH=& ...
- linux 读取 USB HID鼠标坐标和点击 在 LCD上显示
首先要,编译内核时启用了 USB HID 设备.启用了 鼠标 . 在开发板上插入usb 时会有如下提示. 可以看到,多了一个 mouse0 和 eventX 打出来的是我的 联想鼠标. 1, 在 终端 ...
- 16 bit 的灰度图如何显示
16 bit 的灰度图如何在QT中显示 用Mat构造的 16 bit 灰度图 无法直接显示,需要转换成 8 bit 的灰度图在QT中显示, 使用OpenCV自带的最大最小值归一法, cv::norma ...
- 从视频文件中读入数据-->将数据转换为灰度图-->对图像做canny边缘检测-->将这三个结构显示在一个图像中
//从视频文件中读入数据-->将数据转换为灰度图-->对图像做canny边缘检测-->将这三个结构显示在一个图像中 //作者:sandy //时间:2015-10-10 #inclu ...
- Matlab 如何/怎样 读取图片 显示图片 转换成灰度图
% 读取图片 im = imread('路径') >> im = imread('ny.png'); % 显示图片 imshow(im) >> imshow(im) % 转换成 ...
- OpenLayers在地图上显示统计图,饼图线状图柱状图,修复统计图跳动的问题
环境介绍 Openlayers ol.js v5.3.0 Highcharts highcharts.js v7.0.1 jquery jquery-3.3.1.js v3.3.1 显示效果 地图放大 ...
- python显示灰度图
import matplotlib import matplotlib.pyplot as plt %matplotlib inline im=plt.imread('../lena.jpg', py ...
- 自制单片机之十六……将文字或图形转成LCD上使用的C51字模数据
这一讲说说如何用取模软件将图形转成数据吧,有很多人反复问我这个问题,我就再罗嗦下吧! 取字模的软件有很多款.有的只能将文字转成字模数据,有的既可将文本文字转字模也能将图片转成点阵数据.在这里我就介绍一 ...
- Qt生成灰度图(转载)
Qt生成灰度图(转载) 项目中用到大量基础图像处理知识,其中灰度图的生成是很重要的一环. 先补充一些基础知识: ------------------------------------------ ...
随机推荐
- How to Analyze Java Thread Dumps--reference
原文地址:http://architects.dzone.com/articles/how-analyze-java-thread-dumps The Performance Zone is pres ...
- Oracle 通过sql profile为sql语句加hint
sql profile最大的优点是在不修改sql语句和会话执行环境的情况下去优化sql的执行效率,适合无法在应用程序中修改sql时.sql profile最常用方法大概是:--创建产生sql tuni ...
- Listview实现分页下载
分析: * 1.初始控件,展示第一页数据 * 2.设置触发条件 * 1.设置滚动监听 * 2.判断是否在底部 * 3.判断是否停止滚动 * 4.更改网络请求参数为下一页 * 5.异步网络请求 * 6. ...
- jemalloc源码结构分析(二):CPU字节对齐算法
在调用arena_malloc_small过程中,要根据申请内存大小,进行对齐计算,然后分配一个整块儿.算法如下: 1)定义一个SIZE_CLASSES宏,它主要用于生成后面两个表,small_siz ...
- Android 自学之列表选择框Spinner
列表选择框(Spinner)与Swing编程里面的Spinner不同,这里的Spinner其实就是一个列表选项框. Spinner是ViewGroup的间接子类,因此他也可作为容器使用. Spinne ...
- Android 自学之自动完成文本框 AutoCompleteTextView
自动完成文本框(AutoCompleteTextView)从EditText派生而出,实际上他也是一个编辑框,但他比普通的编辑框多了一个功能:当用户输入一定字符后,自动完成文本框会显示一个下拉菜单,供 ...
- java中volatile关键字的含义 (转载)
在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言是支持多线程的,为了解决线程并发的问题,在语 ...
- 服务器的SVN项目版本较低,check out 下来后报错
check out下来后报错提示: svn: E155036: Please see the 'svn upgrade' commandsvn: E155036: Working copy '/hom ...
- .Net 动态代理,AOP
.Net 动态代理,AOP 直接上代码了. /***************************************** * author:jinshuai * * E-mail:redfox ...
- Ajax学习笔记(1)
Ajax全称为Asynchronous Javascript and XML.一般用于页面数据交互响应,最大的好处是响应时无需刷新页面. Ajax的优点: 1.不需要插件的支持.用户只需允许javas ...