本帖最后由 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); } |