Image zoom algorithm

Project background: The blogger has done a project to collect data from a camera and then display video data on the LCD. If the resolution of one frame of data collected by our camera is greater than the resolution of our LCD, then the LCD cannot display the entire Image, at this time we have to zoom such a frame of picture, and then display it on the LCD.

 

This article uses the nearest neighbor sampling interpolation method to scale the picture. For example, if the original image has 100 points, if you want to zoom 10 times, then you need to take 10 points (point number) such as 0 10 20 30. . . 100 (nothing else).

Here we analyze directly by the program: First, we use  the input resolution / resolution after compression   can obtain a scaling value k , k based on this value to find out what we want to save on the original vertical and horizontal lines . The intersection of the horizontal and vertical lines is the point we want to save.

/**********************************************************************
 * 函数名称: 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;
}

 

 

Published 42 original articles · Like 10 · Visitors 10,000+

Guess you like

Origin blog.csdn.net/qq_37659294/article/details/104382032