#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#pragma pack(1) //設定取消位元組對齊
// 檔案資訊結構體
typedef struct tag_bitmap_file_header
{
unsigned short file_type; // 檔案標識,為字母ASCII碼“BM”
unsigned int file_size; // 點陣圖檔案大小,以位元組為單位
unsigned short reserved1; // 點陣圖檔案保留字,必須為0
unsigned short reserved2; // 點陣圖檔案保留字,必須為0
unsigned int offset_bits; // 檔案開始到點陣圖資料開始之間的偏移量位元組
}bmp_file_header;
// 點陣圖資訊結構體
typedef struct tag_bitmap_info_header
{
unsigned int bitmap_info_size; // 影像描述資訊快的大小,常為28H
int bitmap_width; // 影像寬度
int bitmap_height; // 影像高度
unsigned short planes; // 影像的plane總數(恆為1)
unsigned short image_depth; // 記錄顏色的位數取值1(雙色),4,6,24,,3
unsigned int compression; // 資料壓縮方式(0:不壓縮;1:8位壓縮;2:4位壓縮
unsigned int image_size; // 影像區資料的大小,必須是4的倍數
int x_pels_permeter; // 水平每米有多少畫素,在裝置無關點陣圖中,填寫00H
int y_pels_permeter; // 垂直每米有多少畫素,在裝置無關點陣圖中,填寫00H
unsigned int color_used; // 此影像所有的顏色數,不用,固定為0
unsigned int color_important; // 重要顏色數,不用,固定為0
}bmp_info_header;
#pragma pack() //設定為位元組對齊
int main()
{
//1.開啟bmp圖片檔案
FILE * bmp_fp = fopen("demo.bmp","rb");
if(NULL == bmp_fp)
{
printf("open bmp file faild\n");
return -1;
}
//2.讀取BMP圖片檔案的影像資訊,獲取BMP的寬和高
bmp_info_header headerinfo; //BMP標頭檔案資訊結構體
bmp_file_header newheaderinfo1;
bmp_info_header newheaderinfo; //BMP標頭檔案資訊結構體
fseek(bmp_fp,14,SEEK_SET);
fread(&headerinfo,1,40,bmp_fp); //讀取BMP標頭檔案資訊
printf("current bmp width = %d\ncurrent bmp height = %d\n",headerinfo.bitmap_width,headerinfo.bitmap_height);//輸出BMP圖片寬度和高度資訊
//3.讀取BMP圖片的顏色分量
int pxsize = headerinfo.bitmap_width*headerinfo.bitmap_height*headerinfo.image_depth/8;
printf("pxsize = %d\n",pxsize);
char bmp_buf[pxsize]; //申請圖片畫素大小的緩衝區
fread(bmp_buf,1,pxsize,bmp_fp); //讀取BMP顏色分量資料
fseek(bmp_fp,0,SEEK_SET); //設定游標為檔案開頭
fread(&newheaderinfo1,1,14,bmp_fp); //讀取BMP標頭檔案資訊
newheaderinfo1.file_size = 400*240*3;
fread(&newheaderinfo,1,40,bmp_fp); //讀取BMP標頭檔案資訊
newheaderinfo.bitmap_width = 400;
newheaderinfo.bitmap_height = 240;
fclose(bmp_fp);
char newbmp_buf[pxsize/4];
int cnt = 0;
for(int y = 0;y < 480; y+=2)
{
for(int x = 0; x < 800 ;x+=2)
{
for(int k=0; k<3; k++)
{
//newbmp_buf[cnt] = bmp_buf[(y*480+x)*3+k];
newbmp_buf[cnt] = bmp_buf[(y*800+x)*3+k];
cnt++;
}
}
}
//printf("%d\n",cnt);
//開啟待寫入的檔案
FILE * newbmp_fp = fopen("newdemo.bmp","wb+");
if(NULL == newbmp_fp)
{
printf("open bmp file faild\n");
return -1;
}
int fp = fwrite(&newheaderinfo1,1,14,newbmp_fp);
if(fp != 14)
{
printf("write failed\n");
}
fwrite(&newheaderinfo,1,40,newbmp_fp);
fwrite(&newbmp_buf,1,400*240*3,newbmp_fp);
fseek(bmp_fp,54,SEEK_SET); //設定游標為檔案顏色分量開頭
char Newbmp_buf[pxsize/4];
fread(Newbmp_buf,1,pxsize/4,newbmp_fp);
fclose(newbmp_fp);
//5.開啟LCD
int lcd_fd = open("/dev/fb0",O_RDWR);
//6.對LCD進行記憶體對映
int lcd_pxsize = 800*480*4;
int * lcd_mp = (int *)mmap(NULL,lcd_pxsize,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);
//7.迴圈的把BMP影像的顏色分量依次寫入到LCD的畫素點中
int i = 0;
int data = 0;
for (int y = 240-1; y >= 0; y--)
{
for (int x = 0; x < 400 ; ++x)
{
//把BMP圖片的一個畫素點的顏色分量轉換為LCD螢幕的一個畫素點的顏色分量格式 ARGB <--- BGR
data |= Newbmp_buf[i]; //B
data |= Newbmp_buf[i+1]<<8; //G
data |= Newbmp_buf[i+2]<<16; //R
lcd_mp[800*y + x] = data; //BGR BGR BGR ....
i+=3;
data = 0;
}
}
//8.關閉LCD
close(lcd_fd);
munmap(lcd_mp,lcd_pxsize);
return 0;
}