BMP格式圖片縮放及在LCD屏幕展示練習

来源:https://www.cnblogs.com/cino/p/18188299
-Advertisement-
Play Games

/** * @brief :實現bmp格式圖片的2倍縮小功能,並輸出新的目標bmp格式文件。最後利用800*480的開發板,展示縮放後的bmp文件 因為只是進行函數練習,未採用函數封裝的做法 * @author [email protected] * @date 2024/05/12 * Cop ...


/**
 * @brief :實現bmp格式圖片的2倍縮小功能,並輸出新的目標bmp格式文件。最後利用800*480的開發板,展示縮放後的bmp文件
            因為只是進行函數練習,未採用函數封裝的做法
 * @author [email protected]
 * @date 2024/05/12
 * CopyRight (c)  2023-2024   [email protected]   All Right Reseverd
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <stdlib.h>

#define MUL 2 // 規定縮放倍數,多重倍數需後續筆者繼續優化

#pragma pack(1)                    // 取消預設位元組對齊
typedef struct tagBITMAPFILEHEADER // bmp格式圖片的文件信息頭1
{
    unsigned short type;      // 文件標識,字母編碼“BM”
    unsigned int size;        // 點陣圖文件大小,以位元組為單位
    unsigned short reserved1; // 點陣圖文件保留字,為0
    unsigned short reserved2; // 點陣圖文件保留字,為0
    unsigned int offBits;     // 文件開始到點陣圖數據開始自建的偏移量,單位位元組
} BMF_HEADER;

typedef struct tagBITMAPINFOHEADER // bmp格式圖片的文件信息頭2
{
    unsigned int biSize;         // 圖像描述信息塊大小,常為28H
    int width;                   // 圖像寬度
    int height;                  // 圖像高度
    unsigned short biPlanes;     // 圖像plane總數(恆為1)
    unsigned short biBit_depth;  // 記錄顏色的位數取值1
    unsigned int biCompression;  // 數據壓縮方式
    unsigned int biSizeImage;    // 圖像區數據的大小,必須是4的倍數
    int biXPelsPerMeter;         // 水平每米像素
    int biYPelsPerMeter;         // 垂直每米像素
    unsigned int biClrUsed;      // 圖像所用顏色素,不用,固定為0
    unsigned int biClrImportant; // 重要顏色數,不用,固定為0
} BMFI_HEADER;
#pragma pack() // 恢復預設位元組對齊

int main(int argc, char *argv[])
{
    // 1.打開源圖片文件,併進行信息提取
    BMF_HEADER S1;
    BMFI_HEADER S2;                       // 用於頭文件信息提取
    FILE *bmp_fp = fopen(argv[1], "rb+"); // 打開源圖片文件
    if (argc != 3)                        // 錯誤判斷
    {
        printf("Usage:%s <srcfile><dstfile>\n", argv[0]);
        exit(1);
    }
    if (!bmp_fp) // 錯誤判斷
    {
        perror("fopen()");
        exit(1);
    }
    fread(&S1, 1, 14, bmp_fp); // 進行源圖片的頭文件信息提取
    fread(&S2, 1, 40, bmp_fp);

    int bmp_size = S2.width * S2.height * S2.biBit_depth / 8;
    char bmp_buf[bmp_size];              // 申請空間,存放源圖片信息
    fread(bmp_buf, 1, bmp_size, bmp_fp); // 讀取圖片文件信息
    fclose(bmp_fp);                      // 關掉源圖片文件

    // 2.進行源圖片的數據處理
    /*
    此處的思路,是先將圖片信息進行縮放,即用一個新的數組進行採樣,每MUL個原數組拼成一個新的數組
    然後再利用採樣好的數據進行輸出到文件或者LCD
    因此此處僅考慮按順序採樣即可,保證數據不丟失
    */
    char newbuf[bmp_size / MUL / MUL]; // 申請數組,存放重新採樣後的圖片信息
    int cnt = 0;
    for (int y = 0; y < S2.height; y += MUL) // 存放按倍數縮放採樣後的圖片信息,每次前進MUL個像素點
    {
        for (int x = 0; x < S2.width; x += MUL)
        {
            newbuf[cnt++] = bmp_buf[(y * S2.width + x) * 3];     // B
            newbuf[cnt++] = bmp_buf[(y * S2.width + x) * 3 + 1]; // G
            newbuf[cnt++] = bmp_buf[(y * S2.width + x) * 3 + 2]; // R
        }
    }

    // 3.創建新的圖片文件,並存入相關信息
    FILE *new_fp = fopen(argv[2], "wb+"); // 創建新的圖片文件
    if (!new_fp)                          // 錯誤判斷
    {
        perror("fopen()");
        exit(1);
    }
    S2.width = S2.width / MUL;
    S2.height = S2.height / MUL;
    fwrite(&S1, 1, 14, new_fp); // 往新的圖片文件寫進內容;先寫頭1
    fwrite(&S2, 1, 40, new_fp); // 往新的圖片文件寫進內容;寫頭2
    fwrite(&newbuf, 1, bmp_size / MUL / MUL, new_fp);
    fclose(new_fp);

    // 4.打開LCD設備操作,並申請映射空間
    int lcd_fd = open("/dev/fb0", O_RDWR); // 打開LCD設備
    int *lcd_map = (int *)mmap(NULL,
                               800 * 480 * 4, // 申請映射空間,此處一定要是設備的尺寸
                               PROT_READ | PROT_WRITE,
                               MAP_SHARED,
                               lcd_fd,
                               0);
    // 5.設置圖片位置偏移量,並將圖片信息寫入映射記憶體
    int X, Y;
    printf("Please enter the location(X Y):\n"); // X和Y是相對於左上角點的位置,讓用戶輸入
    scanf("%d %d", &X, &Y);
    int i = 0;
    int data = 0;
    for (int y = S2.height / MUL - 1; y >= 0; y--) // 此處要寫新圖片的尺寸,以完整的輸入整張圖片信息
    {
        for (int x = 0; x < S2.width / MUL; ++x)
        {
            // 把BMP圖片的一個像素點的顏色分量轉換為LCD屏幕的一個像素點的顏色分量格式  ARGB <--- BGR
            data |= newbuf[i];                     // B
            data |= newbuf[i + 1] << 8;            // G
            data |= newbuf[i + 2] << 16;           // R
            lcd_map[800 * (y + Y) + x + X] = data; // 此處要寫LCD屏幕的高度
            i += 3;
            data = 0;
        }
    }
    close(lcd_fd);
    munmap(lcd_map, 800 * 480 * 4); // 此處要寫LCD屏幕的尺寸
    return 0;
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • C# 是一種簡單、現代、面向對象和類型安全的編程語言。.NET 是由 Microsoft 創建的開發平臺,平臺包含了語言規範、工具、運行,支持開發各種應用,如Web、移動、桌面等。.NET框架有多個實現,如.NET Framework、.NET Core(及後續的.NET 5+版本),以及社區版本M... ...
  • 十年沉澱,重啟開發之路 十年前,我沉浸在開發的海洋中,每日與代碼為伍,與演算法共舞。那時的我,滿懷激情,對技術的追求近乎狂熱。然而,隨著歲月的流逝,生活的忙碌逐漸占據了我的大部分時間,讓我無暇顧及技術的沉澱與積累。 十年間,我經歷了職業生涯的起伏和變遷。從初出茅廬的菜鳥到逐漸嶄露頭角的開發者,我見證了 ...
  • 基於.NET Framework 4.8 開發的深度學習模型部署測試平臺,提供了YOLO框架的主流系列模型,包括YOLOv8~v9,以及其系列下的Det、Seg、Pose、Obb、Cls等應用場景,同時支持圖像與視頻檢測。模型部署引擎使用的是OpenVINO™、TensorRT、ONNX runti... ...
  • 目錄一、什麼是PXE1、簡介2、工作模式3、工作流程二、什麼是Kickstart1、簡介2、觸發方式三、無人值守安裝系統工作流程四、實驗部署1、環境準備2、服務端:關閉防火牆和selinux3、添加一張僅主機的網卡4、配置僅主機的網卡4.1、修改網路連接名4.2、配IP地址4.3、重啟網卡5、配置D ...
  • 文件IO練習題 設計程式,實現在LCD上任意位置顯示一張任意大小的色深為24bit的bmp圖片,要求圖像不失真可以在開發板的LCD上顯示。 代碼: /*************************************************************************** ...
  • 解題的關鍵在於 顯示圖片的雙重for迴圈條件與目標位置的結合,且該程式輸入的坐標值為圖片左上角像素點坐標 ...
  • 目錄文件IO知識點補給1.FAT32與NTFS文件系統的區別?2.MMU的概述和作用3.簡述Linux系統內核的作用4.瞭解Linux系統目錄和文件夾的區別標準IO介面一、打開文件函數1:fopen二、讀取數據(1)字元讀取函數2:fgetc函數3:getc函數4:getchar(2)按行讀取函數5 ...
  • 痞子衡嵌入式半月刊: 第 100 期 這裡分享嵌入式領域有用有趣的項目/工具以及一些熱點新聞,農曆年分二十四節氣,希望在每個交節之日準時發佈一期。 本期刊是開源項目(GitHub: JayHeng/pzh-mcu-bi-weekly),歡迎提交 issue,投稿或推薦你知道的嵌入式那些事兒。 上期回 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...