首頁  >  問答  >  主體

c语言 - bmp图像如何用c/c++处理?

求代码,用c/c++进行bmp图像的处理,处理内容包括旋转,灰度图,二值图等等。

巴扎黑巴扎黑2714 天前853

全部回覆(10)我來回復

  • 怪我咯

    怪我咯2017-04-17 13:11:18

    這麼巧?
    發現各種找到的函式庫都非常巨大,抽象層次也很高,無法滿足需求
    自己剛寫了一個C++讀寫bmp的類,支援8位元灰階圖,24位元RGB圖。

    https://github.com/edimetia3d/simpleBMP

    程式碼很短,其實看原始碼10分鐘就了解做了些什麼。

    簡單說明一下:
    沒有任何抽象,讀取就是把bmp裡的所有資料(是的,每個位元組都用上了)都映射到某個定義過的變數。
    保存就是把這些變數再寫回磁碟。

    其實原本打算完全按照C來寫的,對動態記憶體不太感冒,所以用了vector
    讀寫部分用的還是fread fwrite,把vector的部分換成動態記憶體就完全可以在C下運行了。
    每個變數的意思見
    http://www.cnblogs.com/xiekeli/archive/2012/05/09/2491191.html
    具體映射關係如下。

    typedef struct {
        unsigned short bfType;
        unsigned long bfSize;
        unsigned short bfReserved1;
        unsigned short bfReserved2;
        unsigned long bfOffBits;
    } ClBitMapFileHeader;
    
    typedef struct {
        unsigned long biSize;
        long biWidth;
        long biHeight;
        unsigned short biPlanes;
        unsigned short biBitCount;
        unsigned long biCompression;
        unsigned long biSizeImage;
        long biXPelsPerMeter;
        long biYPelsPerMeter;
        unsigned long biClrUsed;
        unsigned long biClrImportant;
    } ClBitMapInfoHeader;
    
    typedef struct {
        unsigned char rgbBlue;
        unsigned char rgbGreen;
        unsigned char rgbRed;
        unsigned char rgbReserved;
    } ClrgbMap;
    
    class ClImgBMP {
    public:
        ClBitMapFileHeader bmpFileHeaderData;
        ClBitMapInfoHeader bmpInfoHeaderData;
        ClrgbMap colorMap[256];
        vector<unsigned char> imgData;
    
        bool LoadImage(const char* path);
        bool SaveImage(const char* path);
    };

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 13:11:18

    使用Windows Imaging Component讀取圖片(相容於bmp、jpg、png等常見格式)

    1、使用CoCreateInstance建立IWICImagingFactory
    2、使用IWICImagingFactory::CreateDecoderFromFilename建立一個IWICBitmapDecoder
    3、使用IWICBitmapDecoder::GetFrameFrameEmapDecoder< CFormatConverter,並使用你喜愛的格式初始化他,使用第三步驟創建好的物件呼叫IWICFormatConverter::Initialize函數
    5、如果第四步創建好的物件呼叫IWICFormatConverter::Initialize函數
    5、如果第四步創建好的物件呼叫IWICFormatConverter::Initialize函數
    5、如果第四步創建好的物件調用IWICFormatConverter轉成IWICBitmapSource,否則就把IWICBitmapFrameDecoder轉為IWICBitmapSource

    6、使用IWICImagingFactory::CreateBitmapFromSource從IWICBitmapSource取得IWICBitmap

    使用Direct2D取得圖形

    鑑於d2d資料較多,請自行查找。首先就是建立一個空的位圖,然後使用這個位圖建立ID2D1RenderTarget,然後使用ID2D1RenderTarget::CreateBitmapFromWicBitmap,從剛才取得的IWICBitmap建立出一個ID2D1Bitmap。這樣你就擁有了兩個bitmap,第一個是從檔案裡面讀進來的,第二個是你建立的一個空白bitmap。 最後使用render target的各種effect、shader和函數,就使用你喜歡的任何效果,譬如旋轉、灰度、二值等,把讀進來的bitmap畫到空白的bitmap上去。最後把bitmap一保存,就搞定了。

    總結

    最困難的部分就是讀寫文件,效果什麼的都是現成的。 Direct2D比GDI+還要好用,效能還高,絕對不相容Windows XP。 <🎜>

    回覆
    0
  • 大家讲道理

    大家讲道理2017-04-17 13:11:18

    OpenCV吧

    回覆
    0
  • 黄舟

    黄舟2017-04-17 13:11:18

    我自己通常都用這個函式庫
    https://github.com/nothings/stb

    回覆
    0
  • 巴扎黑

    巴扎黑2017-04-17 13:11:18

    imagick http://www.imagemagick.org

    回覆
    0
  • 黄舟

    黄舟2017-04-17 13:11:18

    BMP這種格式實在是過於簡單了,說句實話,手解都沒什麼大錯。

    根據你具體需求的多寡,以及你硬體條件的好壞(極端假設:例如ARM Cortex M0的低檔32位元單晶片),以下任一都是不錯的選擇:

    • opencv,本身就是c++函式庫

    • imagemagick的magick++函式庫 http://www.imagemagick.org/script/magick++.php

    • 各種簡單、專門的bmp函式庫,這個選擇就很多了,但是通常這些函式庫只能讀bmp就是了。
      例如我曾經用過EasyBMP http://easybmp.sourceforge.net/

    • 手解解得好也行

    實際上最為推薦opencv,這個可以最大限度的獲得輸入其他文件格式,以及後續各種圖形演算法的便利。

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-17 13:11:18

    有兩種方式,
    1 用第三方函式庫,除了上述的之外,還可以選skia

    2 網路上搜一段讀bmp到二維數組的程式碼以及寫二維數組到bmp的程式碼,你需要功能比較簡單,完全可以自己實作。旋轉靠的是矩陣轉換和內插,灰階圖和二值圖直接根據定義計算就可以了。

    回覆
    0
  • 高洛峰

    高洛峰2017-04-17 13:11:18

    STB
    https://github.com/nothings/stb
    FreeImage
    NvImage
    還有我自己擼的庫
    ImagePP
    https://github. com/lalalaring/ImagePP

    回覆
    0
  • 阿神

    阿神2017-04-17 13:11:18

    opencv gdal

    回覆
    0
  • 怪我咯

    怪我咯2017-04-17 13:11:18

    BMP的數據,沒有任何壓縮,都是放在檔案頭之後的地方,手解沒難度。其主要是文件頭+數據。而且文件頭也沒有什麼難度,很清晰,具體地BMP頭,樓主可以去搜尋一下。

    建議樓主如果時間上來得及,可以手解,這樣可以更了解BMP檔案的格式。

    回覆
    0
  • 取消回覆