在LCD螢幕上任意位置開啟以縮減圖片(待修改)

Zeratul$$$發表於2024-05-12
#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;

}

相關文章