打印
[ARM入门]

BMP格式图像显示的程序代码

[复制链接]
1331|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
nicholasldf|  楼主 | 2016-1-13 15:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 nicholasldf 于 2016-1-13 16:13 编辑

参数StartX和StartY为图像在LCD显示的其实位置,pbmpfile为bitmap图像文件句柄。
//从SD卡读取每行像素的缓冲区
/* fit lcd hor width, consider 32bitbmp->max */
uint8_t image_data_buff[LCD_HOR_RESOLUTION* 4];//1920
/*
*******************************************************************************
* function    : BSP_LCD_DrawBitmap
* Description : Draws a bitmap picture
* Argument(s) : StartX - LCD X position,StartY - LCD Y position, pbmpfile - Bmp picture file handler.
* Return(s)   : none
*******************************************************************************
*/
void BSP_LCD_DrawBitmap(uint32_t StartX,uint32_t StartY, FIL *pbmpfile)
{
    uint32_ti, j, k, bytesPerPixel, bytesPerLine, bytesread;
    uint32_tEndX, EndY, color;
    FRESULT  res;
    BITMAP_HEADER  BitMapHeader;
   
    //readbitmap header
    res= f_lseek (pbmpfile, 0);
    res= f_read  (pbmpfile, &BitMapHeader,sizeof(BITMAP_HEADER), &bytesread);
    if(FR_OK!= res)  return;
   
    //-------------------testcode start - show bmp image info-------------------
    BSP_LCD_SetForeColor(COLOR_CODE_BLACK);
    BSP_LCD_FillRect(0,0, LCD_HOR_RESOLUTION-1, 80);
    BSP_LCD_SetForeColor(COLOR_CODE_WHITE);
    BSP_LCD_Printf(0,0 , ASCII_FONT_CODE_16x16, "bitmap image infomation:");
    BSP_LCD_Printf(0,16, ASCII_FONT_CODE_16x16, "image Width:%d",BitMapHeader.bminfoHeader.biWidth);
    BSP_LCD_Printf(0,32, ASCII_FONT_CODE_16x16, "image biHeight:%d",BitMapHeader.bminfoHeader.biHeight);
    BSP_LCD_Printf(0,48, ASCII_FONT_CODE_16x16, "pixel BitCount:%d",BitMapHeader.bminfoHeader.biBitCount);
    BSP_LCD_Printf(0,64, ASCII_FONT_CODE_16x16, "Compression:%d",BitMapHeader.bminfoHeader.biCompression);
    //-------------------testcode end - show bmp image info-------------------
   
    if(0x4D42!= BitMapHeader.bmfileHeader.bfType) return;
    if(BitMapHeader.bminfoHeader.biBitCount< 16)  return;
    if(1==BitMapHeader.bminfoHeader.biCompression|| 2==BitMapHeader.bminfoHeader.biCompression) return;
   
    //LCDSet Windows
    EndX= StartX + BitMapHeader.bminfoHeader.biWidth - 1;
    EndY= StartY + BitMapHeader.bminfoHeader.biHeight - 1;
    if(EndX>= LCD_HOR_RESOLUTION)  EndX =LCD_HOR_RESOLUTION-1;
    if(EndY>= LCD_VER_RESOLUTION)  EndY =LCD_VER_RESOLUTION-1;
   
    //note- count of image data every line must be multiple of 4 bytes
    bytesPerPixel= BitMapHeader.bminfoHeader.biBitCount / 8;
    bytesPerLine  = bytesPerPixel *BitMapHeader.bminfoHeader.biWidth;
    if(bytesPerLine% 4)  bytesPerLine = bytesPerLine + 4 -(bytesPerLine % 4);
   
    /*Prepare to write GRAM */
    //setdisplay direction, because bmp image is inverted
    BSP_LCD_Set_WriteDir(LCDWriteDir_L2R_D2U);
    //SetWindows
    BSP_LCD_SetWindows(StartX,StartY, EndX, EndY);
    //startwrite gui ram
    BSP_LCD_WriteCmd(lcd_device.WriteRamCmd);
   
    for(j= StartY; j <= EndY; j++) {
        //newline
        k= BitMapHeader.bmfileHeader.bfOffBits + bytesPerLine * (j-StartY);
        res= f_lseek (pbmpfile, k);
#if 1
//条件选择:使用大数组uint8_timage_data_buff[LCD_HOR_RESOLUTION * 4]作为缓冲区
//---------------------------large rambuffer start---------------------------
        //everytime read one line pixels
        k= bytesPerPixel * BitMapHeader.bminfoHeader.biWidth;
        res= f_read(pbmpfile, image_data_buff, k, &bytesread);
        //error no more data
        if(FR_OK!=res|| 0==bytesread){
            BSP_LCD_Set_WriteDir(LCDWriteDir_L2R_U2D);//restoredisplay direction
            return;
        }
        //displaypixels
        k= 0;
        for(i= StartX; i <= EndX; i++, k++){
            //color- combine RGB
            if(32== BitMapHeader.bminfoHeader.biBitCount){
                color  = (image_data_buff[4*k])>>3;                         //B
                color+= ((uint16_t)(image_data_buff[4*k+1])<<3) & 0x07E0;  //G
                color+= ((uint16_t)(image_data_buff[4*k+2])<<8) & 0xF800;  //R
            }elseif(24 == BitMapHeader.bminfoHeader.biBitCount){
                color  = (image_data_buff[3*k])>>3;                         //B
                color+= ((uint16_t)(image_data_buff[3*k+1])<<3) & 0x07E0;  //G
                color+= ((uint16_t)(image_data_buff[3*k+2])<<8) & 0xF800;  //R
            }elseif(0 == BitMapHeader.bminfoHeader.biCompression){//RGB 555 - BI_RGB
                color  = ((uint16_t)image_data_buff[2*k] &0x1F);           //R
                color+= ((uint16_t)image_data_buff[2*k] & 0xE0)<<1;        //G
                color+= ((uint16_t)image_data_buff[2*k+1])<<9;             //R,G
            }else{//RGB565
                color  = image_data_buff[2*k];                              //G,B
                color +=((uint16_t)image_data_buff[2*k+1])<<8;             //R,G
            }
            //writeLCD
            BSP_LCD_WriteData(color);//Write16-bit GRAM
        }
//----------------------------large rambuffer end----------------------------
#else
//条件选择:使用小数组uint8_tpdata[128]作为图像数据缓冲区
//----------------------------small ram bufferstart---------------------------
        uint32_tpixel;
        uint8_t  pdata[128];
        
        for(i= StartX; i <= EndX;){
            //everytime read 32 pixels
            k= bytesPerPixel * 32;
            res= f_read(pbmpfile, pdata, k, &bytesread);
            //error no more data
            if(FR_OK!=res|| 0==bytesread){
                LCD_Set_WriteDir(LCDWriteDir_L2R_U2D);//restoredisplay direction
                return;
            }
            //display32 pixels
            k= 0;  pixel = 0;
            while(k< bytesread){
                //color- combine RGB
                if(32== BitMapHeader.bminfoHeader.biBitCount){
                    color  = (pdata[k])>>3;                         //B
                    color+= ((uint16_t)(pdata[k+1])<<3) & 0x07E0;  //G
                    color+= ((uint16_t)(pdata[k+2])<<8) & 0xF800;  //R
                }elseif(24 == BitMapHeader.bminfoHeader.biBitCount){
                    color  = (pdata[k])>>3;                         //B
                    color+= ((uint16_t)(pdata[k+1])<<3) & 0x07E0;  //G
                    color+= ((uint16_t)(pdata[k+2])<<8) & 0xF800;  //R
                }elseif(0 == BitMapHeader.bminfoHeader.biCompression){//BI_RGB,RGB 555
                    color  = ((uint16_t)pdata[k] & 0x1F);           //R
                    color+= (((uint16_t)pdata[k]) & 0xE0)<<1;      //G
                    color+= ((uint16_t)pdata[k+1])<<9;             //R,G
                }else{//RGB565
                    color  = pdata[k];                              //G,B
                    color+= ((uint16_t)pdata[k+1])<<8;             //R,G
                }
                //writeLCD
                LCD_Write_Data(color);//Write16-bit GRAM
                //nextpixel
                k+= bytesPerPixel;
                pixel++;
                //reachline end
                if(i+ pixel > EndX)  break;
            }
            //skipwrited pixels
            i+= pixel;
        }
//----------------------------small rambuffer end----------------------------
#endif
    }//endfor(j)
   
    //restoredisplay direction
    BSP_LCD_Set_WriteDir(LCDWriteDir_L2R_U2D);
}

相关帖子

沙发
阿南| | 2016-1-14 11:52 | 只看该作者
不错

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

61

主题

261

帖子

10

粉丝