近邻取样插值方法缩放BGRA图片数据

近邻取样插值原理:

 

对于缩放后图片中的某点 (Dx, Dy) 对应于原图片中的点 (Sx, Sy),它们之间存在如下的比例关系:
(Sx-0)/(SW-0)=(Dx-0)/(DW-0)
(Sy-0)/(SH-0)=(Dy-0)/(DH-0)
因此,已知缩放后图片中的任意一点 (Dx, Dy),可以求得其对应的原图片中的点Sx=Dx*SW/DW,Sy=Dy*SH/DH。

 

 

注意:本程序缩放的是BGRA 4字节数据,如字节数不同需按实际情况进行修改。

/*
*@brief 按大小进行内存拷贝
*@param  v_dst:目的地址;v_src 源地址; c要拷贝的字符数量
*@return 目标数据最后地址.
*/
void * my_memcpy(void *v_dst, const void *v_src, u8 c)
{
    const char *src = v_src;
    char *dst = v_dst;
    while(c--)
    {
        *dst++ = *src++;
    }
    return v_dst;
}


/*
*@brief 近邻取样插值方法缩放BGRA图片数据 
*@param  srcPixelDatas:源数据地址 ,srcPic_width:源数据宽度,srcPic_height:源数据高度
*@param  dstPixelDatas:转换后的数据存储地址 ,dstPic_width:目的数据宽度,dstPic_height:目的数据高度
*@return 成功0,失败-1.
*/
static int PicZoom(u8 *srcPixelDatas, u32 srcPic_width, u32 srcPic_height,
u8 *dstPixelDatas, u32 dstPic_width, u32 dstPic_height)
{
    u32 src_lineBytes = srcPic_width * 4; /*一行的字节数*/
    u32 picZoom_lineBytes = dstPic_width * 4;
    unsigned long dwDstWidth = dstPic_width;
    unsigned long * pdwSrcXTable;
    unsigned long x;
    unsigned long y;
    unsigned long dwSrcY;
    u8 *pucDest;
    u8 * pucSrc;
    unsigned long dwPixelBytes = 4; /*像素字节数*/
    
    pdwSrcXTable = malloc(sizeof(unsigned long)* dwDstWidth);
    if(NULL == pdwSrcXTable)
    {
        return - 1;
    }
    for(x = 0; x < dwDstWidth; x++) /*生成表*/
    {
        pdwSrcXTable[x] = (x *srcPic_width / dstPic_width);
    }
    
    for(y = 0;y < dstPic_height;y++)
    {
        dwSrcY = (y * srcPic_height / dstPic_height);    
        pucDest = dstPixelDatas + y *picZoom_lineBytes;
        pucSrc = srcPixelDatas + dwSrcY *src_lineBytes;
        for(x = 0;x < dwDstWidth; x++)
        {
            my_memcpy(pucDest + x *dwPixelBytes, pucSrc + pdwSrcXTable[x] *dwPixelBytes, dwPixelBytes);
        }
    }
    free(pdwSrcXTable);
    return 0;
}

参考资料:

RGB源数据操作: 实现图片放大、缩小_DS小龙哥的博客-CSDN博客_rgb图像放大

图像缩放算法-lantianyu520-ChinaUnix博客

 

posted @ 2022-05-12 17:13  大龄小凡  阅读(127)  评论(0编辑  收藏  举报