項目背景:博主之前做過一個攝像頭采集數據,然后在LCD上顯示視頻數據的項目,假如我們攝像頭采集的一幀數據的分辨率比我們的LCD的分辨率要大,那么LCD則無法顯示整個圖像,這時候我們就要把這么一幀圖片進行縮放,然后再顯示在LCD上。
?
本文采用的是近鄰取樣插值方法縮放圖片,比如原圖有100個點,想縮放10倍的話,那就要取10個點,(點的編號)比如0 10 20 30 。。。100(其他點就不要了)。
下面我們直接通過程序來分析:首先我們用? 輸入分辨率/壓縮后的分辨率? 可得到一個縮放比例值k,根據這個k值找出我們要保存原圖上哪些豎線和橫線。橫線和豎線的交點就是我們要保存的點。
/*********************************************************************** 函數名稱: PicZoom* 功能描述: 近鄰取樣插值方法縮放圖片* 注意該函數會分配內存來存放縮放后的圖片,用完后要用free函數釋放掉* "近鄰取樣插值"的原理請參考網友"lantianyu520"所著的"圖像縮放算法"* 輸入參數: ptOriginPic - 內含原始圖片的象素數據* ptBigPic - 內含縮放后的圖片的象素數據* 輸出參數: 無* 返 回 值: 0 - 成功, 其他值 - 失敗***********************************************************************/
int PicZoom(PT_PixelDatas ptOriginPic, PT_PixelDatas ptZoomPic)
{unsigned long dwDstWidth = ptZoomPic->iWidth;//壓縮后分辨率的寬度值unsigned long* pdwSrcXTable;unsigned long x;unsigned long y;unsigned long dwSrcY;unsigned char *pucDest;unsigned char *pucSrc;unsigned long dwPixelBytes = ptOriginPic->iBpp/8;if (ptOriginPic->iBpp != ptZoomPic->iBpp){return -1;}//pdwSrcXTable數組用來存放要保存的是哪些“豎線”(保存上圖紅色豎線的位置)pdwSrcXTable = malloc(sizeof(unsigned long) * dwDstWidth);if (NULL == pdwSrcXTable){DBG_PRINTF("malloc error!\n");return -1;}//pdwSrcXTable數組用來存放要保存的是哪些“豎線”(保存上圖紅色豎線的位置)for (x = 0; x < dwDstWidth; x++)//生成表 pdwSrcXTable{pdwSrcXTable[x]=(x*ptOriginPic->iWidth/ptZoomPic->iWidth);}//循環“壓縮后圖片的分辨率的高度”次,也就是開始把要留下的點放進輸出buffer了for (y = 0; y < ptZoomPic->iHeight; y++){ //找出每一次要保存的“橫線” dwSrcY = (y * ptOriginPic->iHeight / ptZoomPic->iHeight);//目的的起始地址pucDest = ptZoomPic->aucPixelDatas + y*ptZoomPic->iLineBytes;//源的起始地址(橫線的位置是每個點的起始地址,豎線的位置是偏移位置)pucSrc = ptOriginPic->aucPixelDatas + dwSrcY*ptOriginPic->iLineBytes;//每條橫線上有dwDstWidth個點要保存for (x = 0; x <dwDstWidth; x++){//結合pdwSrcXTable數組找出要保存的點memcpy(pucDest+x*dwPixelBytes, pucSrc+pdwSrcXTable[x]*dwPixelBytes, dwPixelBytes);}}free(pdwSrcXTable);return 0;
}
?
?