项目背景:博主之前做过一个摄像头采集数据,然后在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;
}