双线性差值算法实现RGB图像缩放-C语言
实现一:存在栈溢出的风险,来自:https://blog.csdn.net/wangjiannuaa/article/details/6598041
1 /**@func gif_get_scale_rgb 2 * @brief 双线性差值算法缩放RGB图片 3 * @param[in] uDstWidth 目的图像宽度 4 * @param[in] uDstHeigth 目的图像高度 5 * @param[out] pDstRgbBuffer 目的图像地址 6 * @param[in] uSrcWidth 源图像宽度 7 * @param[in] uSrcHeigth 源图像高度 8 * @param[in] pSrcRgbBuffer 源图像地址 9 * @return 成功返回:OK 失败返回:ERROR 10 */ 11 static INT32 gif_get_scale_rgb(UINT16 uDstWidth, UINT16 uDstHeigth, UINT8 *pDstRgbBuffer, UINT16 uSrcWidth, UINT16 uSrcHeigth, UINT8 *pSrcRgbBuffer) 12 { 13 DOUBLE fRateW = uDstWidth * 1.0 / uSrcWidth; 14 DOUBLE fRateH = uDstHeigth * 1.0 / uSrcHeigth; 15 16 INT32 iIndexW = 0; 17 INT32 iIndexH = 0; 18 19 DOUBLE fX, fY; 20 21 INT32 iStepSrcImg = uSrcWidth; 22 //INT32 iStepDstImg = uSrcWidth * fRateW; 23 INT32 iStepDstImg = uDstWidth; 24 25 INT32 iX, iY; 26 27 UINT8 bUpLeft, bUpRight, bDownLeft, bDownRight; 28 UINT8 gUpLeft, gUpRight, gDownLeft, gDownRight; 29 UINT8 rUpLeft, rUpRight, rDownLeft, rDownRight; 30 31 UINT8 uB, uG, uR; 32 33 if((NULL == pDstRgbBuffer) || (NULL == pSrcRgbBuffer)) 34 { 35 GIF_ERRORS("Ptr is NULL \n"); 36 return ERROR; 37 } 38 39 for(iIndexH = 0; iIndexH < uDstHeigth/* uSrcHeigth * fRateH */ ; iIndexH++) 40 { 41 for(iIndexW = 0; iIndexW < uDstWidth/* uSrcWidth * fRateW */ ; iIndexW++) 42 { 43 fX = ((double)iIndexW) /fRateW; 44 fY = ((double)iIndexH) /fRateH; 45 46 iX = (int)fX; 47 iY = (int)fY; 48 49 bUpLeft = pSrcRgbBuffer[iY * iStepSrcImg * 3 + iX * 3 + 0]; 50 bUpRight = pSrcRgbBuffer[iY * iStepSrcImg * 3 + (iX + 1) * 3 + 0]; 51 52 bDownLeft = pSrcRgbBuffer[(iY + 1) * iStepSrcImg * 3 + iX * 3 + 0]; 53 bDownRight = pSrcRgbBuffer[(iY + 1) * iStepSrcImg * 3 + (iX + 1) * 3 + 0]; 54 55 gUpLeft = pSrcRgbBuffer[iY * iStepSrcImg * 3 + iX * 3 + 1]; 56 gUpRight = pSrcRgbBuffer[iY * iStepSrcImg * 3 + (iX + 1) * 3 + 1]; 57 58 gDownLeft = pSrcRgbBuffer[(iY + 1) * iStepSrcImg * 3 + iX * 3 + 1]; 59 gDownRight = pSrcRgbBuffer[(iY + 1) * iStepSrcImg * 3 + (iX + 1) * 3 + 1]; 60 61 rUpLeft = pSrcRgbBuffer[iY * iStepSrcImg * 3 + iX * 3 + 2]; 62 rUpRight = pSrcRgbBuffer[iY * iStepSrcImg * 3 + (iX + 1) * 3 + 2]; 63 64 rDownLeft = pSrcRgbBuffer[(iY + 1) * iStepSrcImg * 3 + iX * 3 + 2]; 65 rDownRight = pSrcRgbBuffer[(iY + 1) * iStepSrcImg * 3 + (iX + 1) * 3 + 2]; 66 67 uB = bUpLeft * (iX + 1 - fX) * (iY + 1 - fY) + bUpRight * (fX - iX) * (iY + 1 - fY) 68 + bDownLeft * (iX + 1 - fX) * (fY - iY) + bDownRight * (fX - iX) * (fY - iY); 69 70 uG = gUpLeft * (iX + 1 - fX) * (iY + 1 - fY) + gUpRight * (fX - iX) * (iY + 1 - fY) 71 + gDownLeft * (iX + 1 - fX) * (fY - iY) + gDownRight * (fX - iX) * (fY - iY); 72 73 uR = rUpLeft * (iX + 1 - fX) * (iY + 1 - fY) + rUpRight * (fX - iX) * (iY + 1 - fY) 74 + rDownLeft * (iX + 1 - fX) * (fY - iY) + rDownRight * (fX - iX) * (fY - iY); 75 76 if(iY >= 0 && iY <= uSrcHeigth * 2 && iX >= 0 && iX <= uSrcWidth * 2) 77 { 78 pDstRgbBuffer[iIndexH * iStepDstImg * 3 + iIndexW * 3 + 0] = uB; //B 79 pDstRgbBuffer[iIndexH * iStepDstImg * 3 + iIndexW * 3 + 1] = uG; //G 80 pDstRgbBuffer[iIndexH * iStepDstImg * 3 + iIndexW * 3 + 2] = uR; //R 81 } 82 } 83 } 84 85 return OK; 86 }
实现二:改写自:https://blog.csdn.net/weixin_40647819/article/details/86601070
static INT32 gif_get_scale_rgb(UINT16 uDstWidth, UINT16 uDstHeigth, UINT8 *pDstRgbBuffer, UINT16 uSrcWidth, UINT16 uSrcHeigth, UINT8 *pSrcRgbBuffer)
{
DOUBLE dRateW = (DOUBLE)uDstWidth * 1.0 / (DOUBLE)uSrcWidth;
DOUBLE dRateH = (DOUBLE)uDstHeigth * 1.0 / (DOUBLE)uSrcHeigth;
UINT16 uIndexW = 0;
UINT16 uIndexH = 0;
DOUBLE dCenterH;
DOUBLE dCenterW;
DOUBLE dPointPartu;
DOUBLE dPointPartv;
UINT16 uHeightDown;
UINT16 uHeightUp;
UINT16 uWidthLeft;
UINT16 uWidthRight;
if((NULL == pDstRgbBuffer) || (NULL == pSrcRgbBuffer))
{
GIF_ERRORS("Ptr is NULL \n");
return ERROR;
}
for(uIndexH = 0; uIndexH < uDstHeigth; uIndexH++)
{
//几何中心对齐
dCenterH = ((DOUBLE)uIndexH + 0.5) / dRateH - 0.5;
//防止越界
if (dCenterH<0)
{
dCenterH = 0;
}
if (dCenterH >= (DOUBLE)(uSrcHeigth - 1))
{
dCenterH = (DOUBLE)(uSrcHeigth - 2);
}
//相邻4*4像素的行(坐标)
uHeightDown = (UINT16)floor(dCenterH);
uHeightUp = (UINT16)ceil(dCenterH);
//u为得到浮点型坐标行的小数部分
dPointPartu = dCenterH - (DOUBLE)uHeightDown;
for(uIndexW = 0; uIndexW < uDstWidth; uIndexW++)
{
//几何中心对齐
dCenterW = ((DOUBLE)uIndexW + 0.5) / dRateW - 0.5;
//防止越界
if (dCenterW < 0)
{
dCenterW = 0;
}
if (dCenterW >= (DOUBLE)(uSrcWidth- 1))
{
dCenterW = (DOUBLE)(uSrcWidth - 2);
}
//相邻4*4像素的列(坐标)
uWidthLeft = (UINT16)floor(dCenterW);
uWidthRight = (UINT16)ceil(dCenterW);
//v为得到浮点型坐标列的小数部分
dPointPartv = dCenterW - (DOUBLE)uWidthLeft;
//彩色图像
pDstRgbBuffer[uIndexH * uDstWidth * 3u + uIndexW * 3u + 0u] = (1.0 - dPointPartu) * (1.0 - dPointPartv) * (DOUBLE)pSrcRgbBuffer[uHeightDown * uSrcWidth * 3u + uWidthLeft * 3u + 0u]
+ (1.0 - dPointPartu) * dPointPartv * (DOUBLE)pSrcRgbBuffer[uHeightDown * uSrcWidth * 3u + uWidthRight * 3u + 0u]
+ dPointPartu * (1.0 - dPointPartv) * (DOUBLE)pSrcRgbBuffer[uHeightUp * uSrcWidth * 3u + uWidthLeft * 3u + 0u]
+ dPointPartu * dPointPartv * (DOUBLE)pSrcRgbBuffer[uHeightUp * uSrcWidth * 3u + uWidthRight * 3u + 0u];
pDstRgbBuffer[uIndexH * uDstWidth * 3u + uIndexW * 3u + 1u] = (1.0 - dPointPartu) * (1.0 - dPointPartv) * (DOUBLE)pSrcRgbBuffer[uHeightDown * uSrcWidth * 3u + uWidthLeft * 3u + 1u]
+ (1.0 - dPointPartu) * dPointPartv * (DOUBLE)pSrcRgbBuffer[uHeightDown * uSrcWidth * 3u + uWidthRight * 3u + 1u]
+ dPointPartu * (1.0 - dPointPartv) * (DOUBLE)pSrcRgbBuffer[uHeightUp * uSrcWidth * 3u + uWidthLeft * 3u + 1u]
+ dPointPartu * dPointPartv * (DOUBLE)pSrcRgbBuffer[uHeightUp * uSrcWidth * 3u + uWidthRight * 3u + 1u];
pDstRgbBuffer[uIndexH * uDstWidth * 3u + uIndexW * 3u + 2u] = (1.0 - dPointPartu) * (1.0 - dPointPartv) * (DOUBLE)pSrcRgbBuffer[uHeightDown * uSrcWidth * 3u + uWidthLeft * 3u + 2u]
+ (1.0 - dPointPartu) * dPointPartv * (DOUBLE)pSrcRgbBuffer[uHeightDown * uSrcWidth * 3u + uWidthRight * 3u + 2u]
+ dPointPartu * (1.0 - dPointPartv) * (DOUBLE)pSrcRgbBuffer[uHeightUp * uSrcWidth * 3u + uWidthLeft * 3u + 2u]
+ dPointPartu * dPointPartv * (DOUBLE)pSrcRgbBuffer[uHeightUp * uSrcWidth * 3u + uWidthRight * 3u + 2u];
}
}
return OK;
}