如何解析bmp文件在液晶屏上显示

以前做嵌入式开发时,在裸奔的单片机、arm7或stm32上,显示图片时方式往是将一张图片通过ImagetoLcd等软件,转换成数据烧录在flash中,显示时调出数据,刷到屏上。但对于后来移植了文件系统,这种做法在维护更换图片时就不直观了,今天主要讲讲在有文件系统后,如何调出bmp图片解析显示液晶屏上。

由于手头上没有硬件,就用vs或qt的控件作为一个显示单元,方法:不直接调用系统的接口函数显示图片,而且解析bmp文件格式及图像数据,通过描点的方法显示出来。(mfc和qt下本人都作过试验,本例以qt讲解,用QFrame作为液晶屏显示单元)

一、bmp文件格式:这一部分内容可以去百度

bmpformat.h
#ifndef BMPFORMAT_H
#define BMPFORMAT_H

#include

typedef quint16 UINT16;
typedef quint32 DWORD;
typedef quint32 LONG;
typedef quint16 WORD;
typedef quint8 BYTE;

#pragma pack(push,1)
typedef struct tagBITMAPFILEHEADER
{
UINT16 bfType;
DWORD bfSize;
UINT16 bfReserved1;
UINT16 bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;

typedef struct _tagBMP_INFOHEADER
{
DWORD  biSize;    //4Bytes,INFOHEADER结构体大小,存在其他版本I NFOHEADER,用作区分
LONG   biWidth;    //4Bytes,图像宽度(以像素为单位)
LONG   biHeight;    //4Bytes,图像高度,+:图像存储顺序为Bottom2Top,-:Top2Bottom
WORD   biPlanes;    //2Bytes,图像数据平面,BMP存储RGB数据,因此总为1
WORD   biBitCount;         //2Bytes,图像像素位数
DWORD  biCompression;     //4Bytes,0:不压缩,1:RLE8,2:RLE4
DWORD  biSizeImage;       //4Bytes,4字节对齐的图像数据大小
LONG   biXPelsPerMeter;   //4 Bytes,用象素/米表示的水平分辨率
LONG   biYPelsPerMeter;   //4 Bytes,用象素/米表示的垂直分辨率
DWORD  biClrUsed;          //4 Bytes,实际使用的调色板索引数,0:使用所有的调色板索引
DWORD biClrImportant;     //4 Bytes,重要的调色板索引数,0:所有的调色板索引都重要
}BMP_INFOHEADER;
typedef struct _tagRGBQUAD
{
    BYTE  rgbBlue;       //指定蓝色强度
    BYTE  rgbGreen;      //指定绿色强度
    BYTE  rgbRed;        //指定红色强度
    BYTE  rgbReserved;  //保留,设置为0
} RGBQUAD;
#pragma pack(pop)
#endif // BMPFORMAT_H

二、解析并绘制

void Widget::drawBmp(void)
{
    char data[1024];

    char palette[256][4];
    int w,h;
    int i,j;
    uint8_t r,g,b;
    uint8_t index;
    BITMAPFILEHEADER *pBITMAPFILEHEADER;
    BMP_INFOHEADER *pBMP_INFOHEADER;
    if(drawFlag)
    {

        bmpFile.setFileName(bmpFileName);
        bmpFile.open(QIODevice::ReadOnly);
        //test
//        bmpFile.read(data,512);
//        for(int i=0;i<512;i++)
//            qDebug("%.2x ",data[i]);

        bmpFile.read(data,sizeof(BITMAPFILEHEADER)+sizeof(BMP_INFOHEADER));
        pBITMAPFILEHEADER=(BITMAPFILEHEADER*)data;
        pBMP_INFOHEADER=(BMP_INFOHEADER*)(data+sizeof(BITMAPFILEHEADER));
        qDebug("offset = %d",pBITMAPFILEHEADER->bfOffBits);
        qDebug("biSize = %d",pBMP_INFOHEADER->biSize);
        qDebug("biWidth = %d  biHeight = %d",pBMP_INFOHEADER->biWidth,pBMP_INFOHEADER->biHeight);
        qDebug("biPlanes = %d",pBMP_INFOHEADER->biPlanes);
        qDebug("biBitCount = %d",pBMP_INFOHEADER->biBitCount);
        qDebug("biCompression = %d",pBMP_INFOHEADER->biCompression);
        qDebug("biSizeImage = %d",pBMP_INFOHEADER->biSizeImage);
        qDebug("biClrUsed = %d",pBMP_INFOHEADER->biClrUsed);
        qDebug("biClrImportant = %d",pBMP_INFOHEADER->biClrImportant);

        w=pBMP_INFOHEADER->biWidth;
        h=pBMP_INFOHEADER->biHeight;
        this->resize(w+33,h+52);
        ui->bmpFrame->resize(w,h);
        ui->loadBmpButton->move(10,h+20);
        ui->closeButton->move(100,h+20);

        QPainter painter(ui->bmpFrame);
//        painter.setPen(Qt::gray);
//        painter.setBrush(Qt::green);
//        painter.drawRect(10,10,200,200);
//        painter.setPen(Qt::red);
//        painter.drawLine(0,1,600,1);
//        painter.setPen(QColor(0,255,255));
//        for(int i=0;i<800;i++)
//            painter.drawPoint(300,i);
        // 画图
//        for(i=0; i < h; i++)
//        {
//            for(j=0;jbfOffBits);
        for(i=h; i >0; --i)
        {
            bmpFile.read(data,w);
            for(j=0;j
从bmp文件开始读出信息头
         bmpFile.read(data,sizeof(BITMAPFILEHEADER)+sizeof(BMP_INFOHEADER));
         pBITMAPFILEHEADER=(BITMAPFILEHEADER*)data;
        pBMP_INFOHEADER=(BMP_INFOHEADER*)(data+sizeof(BITMAPFILEHEADER));
打印信息,验证解析是否和文件属性是否一致。
        qDebug("offset = %d",pBITMAPFILEHEADER->bfOffBits);
        qDebug("biSize = %d",pBMP_INFOHEADER->biSize);
        qDebug("biWidth = %d  biHeight = %d",pBMP_INFOHEADER->biWidth,pBMP_INFOHEADER->biHeight);
        qDebug("biPlanes = %d",pBMP_INFOHEADER->biPlanes);
        qDebug("biBitCount = %d",pBMP_INFOHEADER->biBitCount);
        qDebug("biCompression = %d",pBMP_INFOHEADER->biCompression);
        qDebug("biSizeImage = %d",pBMP_INFOHEADER->biSizeImage);
        qDebug("biClrUsed = %d",pBMP_INFOHEADER->biClrUsed);
        qDebug("biClrImportant = %d",pBMP_INFOHEADER->biClrImportant);

初始化显示区域宽和高

       w=pBMP_INFOHEADER->biWidth;
       h=pBMP_INFOHEADER->biHeight;
       this->resize(w+33,h+52);
       ui->bmpFrame->resize(w,h);
       ui->loadBmpButton->move(10,h+20);
       ui->closeButton->move(100,h+20);
        QPainter painter(ui->bmpFrame);
注释部分为测试画图区 区域确定。调i,j的描点方向
//        painter.setPen(Qt::gray);
//        painter.setBrush(Qt::green);
//        painter.drawRect(10,10,200,200);
//        painter.setPen(Qt::red);
//        painter.drawLine(0,1,600,1);
//        painter.setPen(QColor(0,255,255));
//        for(int i=0;i<800;i++)
//            painter.drawPoint(300,i);
// 画图
//        for(i=0; i < h; i++)
//        {
//            for(j=0;j 
  

开始读数据 画图, 如果是16、24、32位真色图片,没有调色板区,直接拿图像数据根据像素位深绘图就行了,

bmpFile.seek(pBITMAPFILEHEADER->bfOffBits);
for(i=h; i >0; --i){     
bmpFile.read(data,w);//读一行像素数据。
for(j=0;j 
 

你可能感兴趣的:(如何解析bmp文件在液晶屏上显示)