2014-06-26 128 views
-2

我有一個bmp文件。我的目標是將文件縮小到文件總大小的70%。我已將bmp標題和像素數組讀入src_buffer。現在我有一個功能,可以攝取像素陣列和src_buffer,位圖寬度(以像素爲單位)src_width,位圖高度(以像素爲單位)src_height和縮小系數r作爲輸入。這個函數在縮放至dest_buffer之後將其輸出寫入,位圖的寬度(像素)爲dest_width,位圖的高度爲dest_height。 現在我想把它寫回bmp格式。這是我面臨困難的地方。要回寫,我發現難以填充structBITMAPINFOHEADERBITMAPFILEHEADER的數據成員。我應該考慮哪些其他事情。我已閱讀關於像素陣列行之間的填充。我該如何實現它。我在C編碼。我不想在這裏編碼的幫助。我想幫助確切的算法來編寫一個BMP文件。按內存大小縮放bmp文件

+2

_現在我有一個函數,可以攝取像素數組和src_buffer,位圖寬度(以像素爲單位)src_width,位圖高度(以像素爲單位)src_height和縮小系數ras input_ ***顯示它和其他相關代碼。***如果你提供你的代碼,那麼更有可能有人可以提供幫助。 – ryyker

+0

該函數看起來像'bool image_resize(WORD * src_buffer,unsigned int src_width,unsigned int src_height,WORD * dest_buffer,int * dest_width,int * dest_height,float r)'。 – tinutomson

+0

'BITMAPFILEHEADER'和'BITMAPINFOHEADER'的哪些成員感到困惑?如果你所做的只是縮小圖像的大小,那麼你應該可以將原始數據用於幾乎所有這些結構的字段,除了那些描述圖像大小的字段。 –

回答

0

我想出瞭如果你不得不縮小一個bmp文件究竟該做什麼。我只會談論24位bmp文件。 24位bmp文件由兩個標頭組成,後面跟着圖像像素數組。 BMP文件中的第一個標題被稱爲BITMAPFILEHEADER,總大小爲14個字節。它看起來有點像這樣。

typedef struct 
{ 
    uint16_t bfType; //2 bytes storing "BM". This means that it is bmp 
    uint32_t bfSize; //4 bytes total file size of bmp. Including both the header and pixel array 
    uint16_t bfReserved1; //Always 0 
    uint16_t bfReserved2; //Always 0 
    uint32_t bfOffBits; // stores 54. (40 +14)Total size of the headers. 
} __attribute__((__packed__)) 
BITMAPFILEHEADER; 

接下來是struct BITMAPINFOHEADER,總大小爲40字節。以下是它的聲明

typedef struct 
{ 
    uint32_t biSize; //40 bytes. Size of the header. 
    int32_t biWidth; //Width of the bitmap image. How many pixel wide is the image. 
    int32_t biHeight; //Height of the bitmap image. 
    uint16_t biPlanes; // Always 1. 
    uint16_t biBitCount; //24 for 24 bit bitmap. Number of bit representing each pixel. 
    uint32_t biCompression; 
    uint32_t biSizeImage; //Total size of bitmap pixel array including padding. 
    int32_t biXPelsPerMeter; 
    int32_t biYPelsPerMeter; 
    uint32_t biClrUsed; 
    uint32_t biClrImportant; 
} __attribute__((__packed__)) 
BITMAPINFOHEADER; 

現在,這2個結構緊接着是像素數組。單個像素由3個字節表示。說它代表的是

typedef struct 
{ 
    uint8_t rgbtBlue; 
    uint8_t rgbtGreen; 
    BYTE rgbtRed; 
} __attribute__((__packed__)) 
RGBTRIPLE; 

我們有一個以線性方式放入的RGBTRIPLE數組。準確地說,像素數由以下公式給出。

BITMAPINFOHEADER.biWidth * BITMAPINFOHEADER.biHeight * sizeof(RGBTRIPLE) 

通過任何單列因此將是所需的內存:

BITMAPINFOHEADER.biWidth * sizeof(RGBTRIPLE) 

這裏是

BITMAPINFOHEADER.biWidth * BITMAPINFOHEADER.biHeight 

的存儲任何圖像信息所需的存儲器的量由下式給出catch,如果任何單個行的總內存不是4個字節的倍數,則將填充添加到該行中,以使其爲4的倍數。說圖像大小爲41X30。存儲一行所需的字節數爲41*3 = 123bytes。因此,一個1字節的填充將以bmp格式添加到此行。因此BITMAPINFOHEADER.biSizeImage = 30 * 124 = 3720 bytes 將bmp解碼爲原始像素數組時,應始終記住刪除這些填充。 同樣,當回寫一個bmp文件(編碼)時,確保你添加了這些額外的填充。 還要注意的是,

BITMAPINFOHEADER.biSizeImage = (BITMAPINFOHEADER.biWidth * sizeof(RGBTRIPLE) +padding) * BITMAPINFOHEADER.biHeight 

或者也可以用一個公式來計算:

BITMAPINFOHEADER.biSizeImage = (((BITMAPINFOHEADER.biWidth * bmpiheader.biBitCount) + 31)/32) * 4 * BITMAPINFOHEADER.biHeight 

請注意,BITMAPINFOHEADER.biBitCount = sizeof(RGBTRIPLE) * 8 = 24 bits 24位位圖。