24位BMP圖片轉565格式16位數組C文件代碼,生成的代碼用于嵌入式程序代碼中圖片文件顯示,BMP圖片以數組的形式保存并讀取,將24位位圖格式轉換為16位位圖格式的源代碼,包括RGB555格式和RGB565格式。
BMP位圖32位轉為24位深度
幫朋友做一個視頻采集和基本處理功能,要求的是.bmp格式
幾天下來,通過directshow進行視頻采集,并抓去圖片保存,按照要求進行業(yè)務處理,以前的處理程序是基于RGB24
而顯示器是32位真彩色,后調整directshow 的grab filter,修改媒體類型,pmt->majortype = MEDIATYPE_Video;
pmt->subtype = MEDIASUBTYPE_RGB24; 結果在業(yè)務中效果不理想,為既保留32位圖,也生成rgb24位圖
硬是將BITMAPINFOHEADER *lpbi 中的值進行強行設置lpbi->biBitCount = 24;
結果是:產生的圖片帶有間斷性的彩色條紋
然后再在谷歌、擺渡中繼續(xù)游泳,沒有實質性進展
無奈,進微軟msdn、gdi+...
接下來的兩天就是惡補BMP知識,發(fā)現彩色條紋應該是RGB32位顏色空間值,對于RGB32與RGB24,它們的像素點空間只差了一個字節(jié),
繼而,自行轉換數據
首先是從directshow中獲取圖像數據
其次是,保留獲取數據的文件頭
然后是轉換位圖數據內容,并將內容另置空間
最后設定BITMAPFILEHEADER文件頭,并寫文件,
為備忘,具體實現如下:
TRY
{
BYTE *buffer = NULL;
hr = m_pWindowsLessControl->GetCurrentImage(&buffer); //這里 m_pWindowsLessControl為IVMRWindowlessControl,進行圖像抓取;
if (!SUCCEEDED(hr))
{
return hr;
}
BITMAPFILEHEADER hdr;
BITMAPINFOHEADER *lpbi = (BITMAPINFOHEADER *)buffer;
//顏色空間轉換,如果為32位位圖,轉換為24
DWORD dwSize24 = 0;
DWORD dwSize32 = lpbi->biSizeImage;
dwSize24 = (dwSize32*3)/4; //RGB32與RGB24的像素點空間差一個字節(jié)
BYTE* pImg24 = new BYTE[dwSize24]; //存放RGB24存儲空間
BYTE* pImg24Temp = pImg24;//設定臨時指針,后續(xù)進行數據管理
BYTE* pImg32 = buffer + sizeof(BITMAPINFOHEADER);//跳過文件頭,定位到數據部分
bool isSize24 = false;
if (lpbi->biBitCount==32)
{
isSize24 = true;
for (DWORD index=0; index<dwSize32/4; index++)
{
unsigned char r = *(pImg32++);
unsigned char g = *(pImg32++);
unsigned char b = *(pImg32++);
pImg32++; //跳過顏色空間alpha分量,實現轉換
*(pImg24++) = r;
*(pImg24++) = g;
*(pImg24++) = b; //賦值
}
//將指針指向新的控件
lpbi->biBitCount = 24;//強行指定
}
int nColors = 1 << lpbi->biBitCount; //按照設定深度,進行顏色計算
if (nColors > 256)
nColors = 0;
hdr.bfType = ((WORD)('M' << 8) | 'B'); // 指定BMP
//進行文件頭設置
hdr.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + nColors * sizeof(RGBQUAD) + lpbi->biSizeImage;
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + lpbi->biSize + nColors * sizeof(RGBQUAD));
//進行位圖寫入
FILE *bmpFile = NULL;
bmpFile = fopen((LPCTSTR)szFile, "wb");//szFile為文件名
if (bmpFile != NULL)
{
fwrite(&hdr, 1, sizeof(BITMAPFILEHEADER), bmpFile);//位圖文件頭
fwrite(buffer, 1, sizeof(BITMAPINFOHEADER), bmpFile);//位圖信息頭
if (!isSize24)
{
fwrite(buffer+sizeof(BITMAPINFOHEADER), 1, nColors * sizeof(RGBQUAD), bmpFile);//顏色表
fwrite(buffer+sizeof(BITMAPINFOHEADER)+nColors * sizeof(RGBQUAD), 1, lpbi->biSizeImage, bmpFile);//位圖數據
}
else
{
fwrite(pImg24Temp,1,dwSize24,bmpFile);
}
}
fclose(bmpFile);
CoTaskMemFree(buffer);//釋放資源
delete pImg24Temp;
return hr;
}
CATCH (CMemoryException, e)
{
}
END_CATCH
}
折騰了兩天,真費勁,特此記錄一下備忘