双线性差值算法实现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;
}

 

posted @ 2022-11-01 21:03  墨尔基阿德斯  阅读(90)  评论(0编辑  收藏  举报